#include <sourcemod>
#include <sdktools>
#include <sdkhooks>
#include <colors>
#include "l4d2_InfectedSpawnApi.inc"

#define PLUGIN_VERSION "2.0"
#define DEBUG 0
#define CVAR_FLAGS FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_NOTIFY


//自定义
#define TANK_Spawn		1		    // 菌种坦克
#define TANK_Smasher	2		    // 粉碎坦克
#define TANK_Warp		 3		    // 瞬移坦克
#define TANK_Meteor	   4			// 陨石坦克
#define TANK_Spitter	  5		    // 酸液坦克
#define TANK_Heal		 6		    // 治愈坦克
#define TANK_Fire		 7		    // 烈焰坦克
#define TANK_Ice		  8		    // 冰霜坦克
#define TANK_Jockey	   9			// 猴子坦克
#define TANK_Ghost		10		    // 幽灵坦克
#define TANK_Shock		11		    // 闪电坦克
#define TANK_Witch		12		    // 女巫坦克
#define TANK_Shield	   13		    // 护盾坦克
#define TANK_Cobalt	   14		    // 神行坦克
#define TANK_Jumper	   15		    // 跳跃坦克
#define TANK_Gravity	  16		// 磁力坦克
#define TANK_Boomer	  17			// 胆汁坦克
#define TANK_RongYan		18	    // 熔岩坦克
#define TANK_ZhongLi		19	    // 重力坦克
#define TANK_KongJu		20		    // 恐惧坦克
#define TANK_DiZhen		21		    // 地震坦克
#define TANK_YouJi		22		    // 游击坦克
#define TANK_Double   23			// 分身坦克
#define TANK_Adrenal	 24		    // 疯狂暴走
#define TANK_RenZhe	 25		        // 忍者坦克

#define TANK_COUNT  25

#define FFADE_IN 0x0001
#define FFADE_OUT 0x0002
#define FFADE_MODULATE 0x0004
#define FFADE_STAYOUT 0x0008
#define FFADE_PURGE 0x0010


#define SURVIVOR	2
#define CLASS_TANK	8
#define MOLOTOV	 0
#define EXPLODE	 1
#define ENTITY_GASCAN	"models/props_junk/gascan001a.mdl"
#define ENTITY_PROPANE	"models/props_junk/propanecanister001a.mdl"

/* Sound */
#define SOUND_EXPLODE	"animation/bombing_run_01.wav"
#define SOUND_SPAWN		"music/pzattack/contusion.wav"
#define SOUND_BCLAW		"weapons/grenade_launcher/grenadefire/grenade_launcher_explode_1.wav"
#define SOUND_GCLAW		"plats/churchbell_end.wav"
#define SOUND_DCLAW		"ambient/random_amb_sounds/randbridgegroan_03.wav"
#define SOUND_QUAKE		"player/charger/hit/charger_smash_02.wav"
#define SOUND_STEEL		"physics/metal/metal_solid_impact_hard5.wav"
#define SOUND_CHANGE	"items/suitchargeok1.wav"
#define SOUND_HOWL		"player/tank/voice/pain/tank_fire_08.wav"
#define SOUND_WARP		"ambient/energy/zap9.wav"

/* Particle */
//#define PARTICLE_SPAWN	"electrical_arc_01_system"
#define PARTICLE_DEATH	"gas_explosion_main"
#define PARTICLE_THIRD	"apc_wheel_smoke1"
#define PARTICLE_FORTH	"aircraft_destroy_fastFireTrail"
//#define PARTICLE_WARP	"water_splash"

#define PARTICLE_SPAWN		"smoker_smokecloud"
#define PARTICLE_FIRE		"aircraft_destroy_fastFireTrail"
#define PARTICLE_WARP		"electrical_arc_01_system"
#define PARTICLE_ICE		"steam_manhole"
#define PARTICLE_SPIT		"spitter_areaofdenial_glow2"
#define PARTICLE_SPITPROJ	"spitter_projectile"
#define PARTICLE_ELEC		"electrical_arc_01_parent"
#define PARTICLE_BLOOD		"boomer_explode_D"
#define PARTICLE_EXPLODE	"boomer_explode"
#define PARTICLE_METEOR		"smoke_medium_01"

new Handle:Msg_Timer							= INVALID_HANDLE;
new tanktype[MAXPLAYERS+1];
new clientlosscount[MAXPLAYERS+1];  // 丢失tank次数
new changehealth = 0;


/* Grobal */
new alpharate;
new visibility;
new g_iLaggedMovementO	= -1;
// 超级tank句柄变量
new TankAbility[MAXPLAYERS+1];
new Rock[MAXPLAYERS+1];
new PlayerSpeed[MAXPLAYERS+1];

/*Handles*/
new Handle:hSuperTanksEnabled = INVALID_HANDLE;
new Handle:hDisplayHealthCvar = INVALID_HANDLE;
new Handle:hWave1Cvar = INVALID_HANDLE;
new Handle:hWave2Cvar = INVALID_HANDLE;
new Handle:hWave3Cvar = INVALID_HANDLE;
new Handle:hFinaleOnly = INVALID_HANDLE;
new Handle:hDefaultTanks = INVALID_HANDLE;
new Handle:hGamemodeCvar = INVALID_HANDLE;

new Handle:hDefaultOverride = INVALID_HANDLE;
new Handle:hDefaultExtraHealth = INVALID_HANDLE;
new Handle:hDefaultSpeed = INVALID_HANDLE;
new Handle:hDefaultThrow = INVALID_HANDLE;
new Handle:hDefaultFireImmunity = INVALID_HANDLE;
// 菌种坦克
new Handle:hSpawnEnabled = INVALID_HANDLE;
new Handle:hSpawnExtraHealth = INVALID_HANDLE;
new Handle:hSpawnSpeed = INVALID_HANDLE;
new Handle:hSpawnThrow = INVALID_HANDLE;
new Handle:hSpawnFireImmunity = INVALID_HANDLE;
new Handle:hSpawnCommonAmount = INVALID_HANDLE;
new Handle:hSpawnCommonInterval = INVALID_HANDLE;
// 毒雾伤害
static const Float:TRACE_TOLERANCE             = 25.0;
new Handle:CloudEnabled = INVALID_HANDLE;
new Handle:CloudDuration = INVALID_HANDLE;
new Handle:CloudRadius = INVALID_HANDLE;
new Handle:CloudDamage = INVALID_HANDLE;
new Handle:CloudShake = INVALID_HANDLE;
new Handle:CloudBlocksRevive = INVALID_HANDLE;
new Handle:SoundPath = INVALID_HANDLE;
new Handle:CloudMeleeSlowEnabled = INVALID_HANDLE;
new Handle:DisplayDamageMessage = INVALID_HANDLE;

static Handle:cvarGameModeActive    = INVALID_HANDLE;
static bool:isAllowedGameMode        = false;

new meleeentinfo;
new bool:isincloud[MAXPLAYERS+1];
new bool:MeleeDelay[MAXPLAYERS+1];
new propinfoghost;
new Float:g_fCloudHrutFreq; // 产生毒雾时间频率
// 粉碎坦克
new Handle:hSmasherEnabled = INVALID_HANDLE;
new Handle:hSmasherExtraHealth = INVALID_HANDLE;
new Handle:hSmasherSpeed = INVALID_HANDLE;
new Handle:hSmasherThrow = INVALID_HANDLE;
new Handle:hSmasherFireImmunity = INVALID_HANDLE;
new Handle:hSmasherMaimDamage = INVALID_HANDLE;
new Handle:hSmasherCrushDamage = INVALID_HANDLE;
new Handle:hSmasherRemoveBody = INVALID_HANDLE;
// 瞬移坦克
new Handle:hWarpEnabled = INVALID_HANDLE;
new Handle:hWarpExtraHealth = INVALID_HANDLE;
new Handle:hWarpSpeed = INVALID_HANDLE;
new Handle:hWarpThrow = INVALID_HANDLE;
new Handle:hWarpFireImmunity = INVALID_HANDLE;
new Handle:hWarpTeleportDelay = INVALID_HANDLE;
new bool:bMoveWarpFlag[MAXPLAYERS+1]; // 瞬移TANK蓄力标志
new iMoveWarpTimes = 20;// 瞬移蓄力时间
new iMoveWarpTimeFlag[MAXPLAYERS+1];  // 蓄力计时
new iMoveWarpAbleFlag[MAXPLAYERS+1];	// 是否显示蓄力
// 陨石坦克
new Handle:hMeteorEnabled = INVALID_HANDLE;
new Handle:hMeteorExtraHealth = INVALID_HANDLE;
new Handle:hMeteorSpeed = INVALID_HANDLE;
new Handle:hMeteorThrow = INVALID_HANDLE;
new Handle:hMeteorFireImmunity = INVALID_HANDLE;
new Handle:hMeteorStormDelay = INVALID_HANDLE;
new Handle:hMeteorStormDamage = INVALID_HANDLE;
// 酸液坦克
new Handle:hSpitterEnabled = INVALID_HANDLE;
new Handle:hSpitterExtraHealth = INVALID_HANDLE;
new Handle:hSpitterSpeed = INVALID_HANDLE;
new Handle:hSpitterThrow = INVALID_HANDLE;
new Handle:hSpitterFireImmunity = INVALID_HANDLE;
new iShowSpitterTimes;	  // 左键几次出一次酸液
new iShowSpitterIndex[MAXPLAYERS+1];
// 治愈坦克
new Handle:hHealEnabled = INVALID_HANDLE;
new Handle:hHealExtraHealth = INVALID_HANDLE;
new Handle:hHealSpeed = INVALID_HANDLE;
new Handle:hHealThrow = INVALID_HANDLE;
new Handle:hHealFireImmunity = INVALID_HANDLE;
new Handle:hHealHealthCommons = INVALID_HANDLE;
new Handle:hHealHealthSpecials = INVALID_HANDLE;
new Handle:hHealHealthTanks = INVALID_HANDLE;
new Handle:hHealDistance = INVALID_HANDLE;
new Float:fHealHealthCommons;// 治愈tank每秒恢复小僵尸血量百分比
new Float:fHealHealthSpecials;// 治愈tank每秒恢复特感血量百分比
new Float:fHealHealthTanks;// 治愈tank每秒恢复坦克血量百分比
new iHealTankDistance;	  // 治愈距离
// 烈焰坦克
new Handle:hFireEnabled = INVALID_HANDLE;
new Handle:hFireExtraHealth = INVALID_HANDLE;
new Handle:hFireSpeed = INVALID_HANDLE;
new Handle:hFireThrow = INVALID_HANDLE;
new Handle:hFireFireImmunity = INVALID_HANDLE;
// 冰霜坦克
new Handle:hIceEnabled = INVALID_HANDLE;
new Handle:hIceExtraHealth = INVALID_HANDLE;
new Handle:hIceSpeed = INVALID_HANDLE;
new Handle:hIceThrow = INVALID_HANDLE;
new Handle:hIceFireImmunity = INVALID_HANDLE;
new Float:fIceNotMoveTimes; // 冰冻时间
// 猴子坦克
new Handle:hJockeyEnabled = INVALID_HANDLE;
new Handle:hJockeyExtraHealth = INVALID_HANDLE;
new Handle:hJockeySpeed = INVALID_HANDLE;
new Handle:hJockeyThrow = INVALID_HANDLE;
new Handle:hJockeyFireImmunity = INVALID_HANDLE;
// 幽灵坦克
new Handle:hGhostEnabled = INVALID_HANDLE;
new Handle:hGhostExtraHealth = INVALID_HANDLE;
new Handle:hGhostSpeed = INVALID_HANDLE;
new Handle:hGhostThrow = INVALID_HANDLE;
new Handle:hGhostFireImmunity = INVALID_HANDLE;
new Handle:hGhostDisarm = INVALID_HANDLE;
new iMoveGhostBeginTimes = 50;// 隐身蓄力开始
new iMoveGhostEndTimes = 5;// 现身蓄力结束
new iMoveGhostBeginTimeFlag[MAXPLAYERS+1];  // 隐身计时
new iMoveGhostEndTimeFlag[MAXPLAYERS+1];  // 现身计时
new iMoveGhostAbleFlag[MAXPLAYERS+1];	// 是否显示蓄力
new iGhostRadiiValue;       // 特感在其身边隐身范围
// 闪电坦克
new Handle:hShockEnabled = INVALID_HANDLE;
new Handle:hShockExtraHealth = INVALID_HANDLE;
new Handle:hShockSpeed = INVALID_HANDLE;
new Handle:hShockThrow = INVALID_HANDLE;
new Handle:hShockFireImmunity = INVALID_HANDLE;
new Handle:hShockStunDamage = INVALID_HANDLE;
new Handle:hShockStunMovement = INVALID_HANDLE;
new Float:g_fSkillViewTime;	// 眩晕时间
new g_iSkillViewTime;	// 眩晕时间
new g_iShockHurtFlag[MAXPLAYERS+1]; // 是否受到闪电tank攻击
new g_iShockHurtTimes[MAXPLAYERS+1];// 受到闪电tank攻击后的时间计时
// 女巫坦克
new Handle:hWitchEnabled = INVALID_HANDLE;
new Handle:hWitchExtraHealth = INVALID_HANDLE;
new Handle:hWitchSpeed = INVALID_HANDLE;
new Handle:hWitchThrow = INVALID_HANDLE;
new Handle:hWitchFireImmunity = INVALID_HANDLE;
new Handle:hWitchMaxWitches = INVALID_HANDLE;
new Float:fWitchSpawnTime;  // 多久产生一个妹子
new Float:fWitchSpawnDistance;  // 多远距离的小僵尸
// 护盾坦克
new Handle:hShieldEnabled = INVALID_HANDLE;
new Handle:hShieldExtraHealth = INVALID_HANDLE;
new Handle:hShieldSpeed = INVALID_HANDLE;
new Handle:hShieldThrow = INVALID_HANDLE;
new Handle:hShieldFireImmunity = INVALID_HANDLE;
new Handle:hShieldShieldsDownInterval = INVALID_HANDLE;
// 神行坦克
new Handle:hCobaltEnabled = INVALID_HANDLE;
new Handle:hCobaltExtraHealth = INVALID_HANDLE;
new Handle:hCobaltSpeed = INVALID_HANDLE;
new Handle:hCobaltThrow = INVALID_HANDLE;
new Handle:hCobaltFireImmunity = INVALID_HANDLE;
new Handle:hCobaltSpecialSpeed = INVALID_HANDLE;
new iMoveCobaltBeginTimes = 50;// 瞬移蓄力时间
new iMoveCobaltEndTimes = 5;// 瞬移蓄力时间
new iMoveCobaltBeginTimeFlag[MAXPLAYERS+1];  // 蓄力计时
new iMoveCobaltEndTimeFlag[MAXPLAYERS+1];  // 蓄力计时
new iMoveCobaltAbleFlag[MAXPLAYERS+1];	// 是否显示蓄力
// 跳跃坦克
new Handle:hJumperEnabled = INVALID_HANDLE;
new Handle:hJumperExtraHealth = INVALID_HANDLE;
new Handle:hJumperSpeed = INVALID_HANDLE;
new Handle:hJumperThrow = INVALID_HANDLE;
new Handle:hJumperFireImmunity = INVALID_HANDLE;
new Handle:hJumperJumpDelay = INVALID_HANDLE;
new bool:bJumperPressDelayp[MAXPLAYERS+1];  // 跳跃延迟
// 磁力坦克
new Handle:hGravityEnabled = INVALID_HANDLE;
new Handle:hGravityExtraHealth = INVALID_HANDLE;
new Handle:hGravitySpeed = INVALID_HANDLE;
new Handle:hGravityThrow = INVALID_HANDLE;
new Handle:hGravityFireImmunity = INVALID_HANDLE;
new Handle:hGravityPullForce = INVALID_HANDLE;
new g_iGravityRadiiYard;	 // 磁力范围
new Float:g_fGravityFreqTimes;      // 磁力作用时间频率，即多长时间作用一次，建议0.1-0.5秒
new Float:g_fGravityFreqYard;       // 每次吸附距离，即上频率作用移动距离
// 胆汁TANK
new Handle:hBoomerEnabled = INVALID_HANDLE;
new Handle:hBoomerExtraHealth = INVALID_HANDLE;
new Handle:hBoomerSpeed = INVALID_HANDLE;
new Handle:hBoomerThrow = INVALID_HANDLE;
new Handle:hBoomerFireImmunity = INVALID_HANDLE;
new iShowBoomerTimes;	  // 左键几次出一次胆汁效果
new iShowBoomerIndex[MAXPLAYERS+1];
// 熔岩
new Handle:hRongYanEnabled = INVALID_HANDLE;
new Handle:hRongYanExtraHealth = INVALID_HANDLE;
new Handle:hRongYanSpeed = INVALID_HANDLE;
new Handle:hRongYanThrow = INVALID_HANDLE;
new Handle:hRongYanFireImmunity = INVALID_HANDLE;
new Handle:sm_lastboss_tankry_hxdmg		= INVALID_HANDLE;
// 重力
new Handle:hZhongLiEnabled = INVALID_HANDLE;
new Handle:hZhongLiExtraHealth = INVALID_HANDLE;
new Handle:hZhongLiSpeed = INVALID_HANDLE;
new Handle:hZhongLiThrow = INVALID_HANDLE;
new Handle:hZhongLiFireImmunity = INVALID_HANDLE;
new Handle:sm_lastboss_gravityinterval 		= INVALID_HANDLE;   // 重力有效时间
new Float:fZhongLiClawValue;      // 被重力击中后重力值
// 恐惧
new Handle:hKongJuEnabled = INVALID_HANDLE;
new Handle:hKongJuExtraHealth = INVALID_HANDLE;
new Handle:hKongJuSpeed = INVALID_HANDLE;
new Handle:hKongJuThrow = INVALID_HANDLE;
new Handle:hKongJuFireImmunity = INVALID_HANDLE;
new Handle:sm_lastboss_dreadinterval 		= INVALID_HANDLE;
new Handle:sm_lastboss_dreadrate	 		= INVALID_HANDLE;
// 地震
new Handle:hDiZhenEnabled = INVALID_HANDLE;
new Handle:hDiZhenExtraHealth = INVALID_HANDLE;
new Handle:hDiZhenSpeed = INVALID_HANDLE;
new Handle:hDiZhenThrow = INVALID_HANDLE;
new Handle:hDiZhenFireImmunity = INVALID_HANDLE;
new Handle:sm_lastboss_quake_radius 		= INVALID_HANDLE;
new Handle:sm_lastboss_quake_force	 		= INVALID_HANDLE;
// 游击
new Handle:hYouJiEnabled = INVALID_HANDLE;
new Handle:hYouJiExtraHealth = INVALID_HANDLE;
new Handle:hYouJiSpeed = INVALID_HANDLE;
new Handle:hYouJiThrow = INVALID_HANDLE;
new Handle:hYouJiFireImmunity = INVALID_HANDLE;
// 分身
new Handle:hDoubleEnabled = INVALID_HANDLE;
new Handle:hDoubleExtraHealth = INVALID_HANDLE;
new Handle:hDoubleSpeed = INVALID_HANDLE;
new Handle:hDoubleThrow = INVALID_HANDLE;
new Handle:hDoubleFireImmunity = INVALID_HANDLE;
new iDoubleTankCounts;  // 分身数量
new bool:bIsDoubleTankSpawn[MAXPLAYERS+1];   // 玩家是否被选中为分身tank
// 疯狂暴走
new Handle:hAdrenalEnabled = INVALID_HANDLE;
new Handle:hAdrenalExtraHealth = INVALID_HANDLE;
new Handle:hAdrenalSpeed = INVALID_HANDLE;
new Handle:hAdrenalThrow = INVALID_HANDLE;
new Handle:hAdrenalFireImmunity = INVALID_HANDLE;
// 忍者
new Handle:hRenZheEnabled = INVALID_HANDLE;
new Handle:hRenZheExtraHealth = INVALID_HANDLE;
new Handle:hRenZheSpeed = INVALID_HANDLE;
new Handle:hRenZheThrow = INVALID_HANDLE;
new Handle:hRenZheFireImmunity = INVALID_HANDLE;
new bool:bRenZhePressDelayp[MAXPLAYERS+1];  // 跳跃延迟

static Handle:SDKSpitBurst 		= INVALID_HANDLE;
static Handle:SDKVomitOnPlayer 		= INVALID_HANDLE;

new bool:bSuperTanksEnabled;
new iWave1Cvar;
new iWave2Cvar;
new iWave3Cvar;
new bool:bFinaleOnly;
new bool:bDisplayHealthCvar;
new bool:bDefaultTanks;

new bool:bTankEnabled[32+1];
new iTankExtraHealth[32+1];
new Float:flTankSpeed[32+1];
new Float:flTankThrow[32+1];
new bool:bTankFireImmunity[32+1];

new bool:bDefaultOverride;
new iSpawnCommonAmount;
new iSpawnCommonInterval;
new iSmasherMaimDamage;
new iSmasherCrushDamage;
new bool:bSmasherRemoveBody;
new iWarpTeleportDelay;
new Float:fMeteorStormDelay;
new Float:flMeteorStormDamage;

new bool:bGhostDisarm;
new iShockStunDamage;
new Float:flShockStunMovement;
new iWitchMaxWitches;
new Float:flShieldShieldsDownInterval;
new Float:flCobaltSpecialSpeed;
new Float:fJumperJumpDelay;
new Float:flGravityPullForce;

new iNumTanks;
new iFrame;

new g_iPlayerMaxHealth[MAXPLAYERS+1];// 最大血量
new Float:fPlayerSpeedValne[MAXPLAYERS+1];   // 因被第三方修改速度后还原值，比如闪电tank攻击减速后还原，不特殊记录所有

new bool:bShieldDemageFlag[MAXPLAYERS+1] = false;// 护盾免伤
public Plugin:myinfo =
{
	name = "超级tank对抗版",
	author = "Yd社区",
	description = "16中tank对抗模式",
	version = PLUGIN_VERSION,
	url = "http://www.l4d2.com/"
}

/******************************************************
*	插件初始化
*******************************************************/
public OnPluginStart()
{
	decl String:game_name[64];
	GetGameFolderName(game_name, sizeof(game_name));
	if (!StrEqual(game_name, "left4dead", false) && !StrEqual(game_name, "left4dead2", false))
	{
		SetFailState("该插件只能用于l4d和l4d2.");
	}
	// 创建特感
	InitInfectedSpawnAPI();

	/* 启用/关闭 */
	hSuperTanksEnabled = CreateConVar("st_on", "1", "是否启用插件？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);

	/**************************** 自定义 *******************************/
	/* 技能 */
	// 菌种
	hSpawnEnabled = CreateConVar("st_spawn", "1", "启用菌种Tank吗?",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hSpawnExtraHealth = CreateConVar("st_spawn_extra_health", "50000.0", "菌种 Tank的生命值",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hSpawnSpeed = CreateConVar("st_spawn_speed", "1.70", "菌种 Tank移动速度",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,2.0);
	hSpawnThrow = CreateConVar("st_spawn_throw", "10.0", "菌种 Tank投石冷却间隔",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,999.0);
	hSpawnFireImmunity = CreateConVar("st_spawn_fire_immunity", "1", "菌种 Tank是否免疫火？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hSpawnCommonAmount = CreateConVar("st_spawn_common_amount", "1", "特感衍生成Tank机率",FCVAR_PLUGIN|FCVAR_NOTIFY,true,1.0,true,50.0);	//默认1-50
	hSpawnCommonInterval = CreateConVar("st_spawn_common_interval", "29900", "衍生间隔",FCVAR_PLUGIN|FCVAR_NOTIFY,true,1.0,true,300.0);	//默认1-60
    CloudEnabled = CreateConVar("l4d_cloud_damage_enabled", "1", "是否开起插件0或1", CVAR_FLAGS);
    CloudDamage = CreateConVar("l4d_cloud_damage_damage", "7.0", " 人类每次受到多少血量伤害", CVAR_FLAGS);
    CloudDuration = CreateConVar("l4d_cloud_damage_time", "8.0", "smoker死后烟雾存在多少秒", CVAR_FLAGS);
    CloudRadius = CreateConVar("l4d_cloud_damage_radius", "400", " 烟雾半径", CVAR_FLAGS);
    SoundPath = CreateConVar("l4d_cloud_damage_sound", "player/survivor/voice/choke_5.wav", "设置受伤后播放的声音文件路径", CVAR_FLAGS);
    CloudMeleeSlowEnabled = CreateConVar("l4d_cloud_meleeslow_enabled", "0", " 是否开起烟雾减速？0或1 （貌似失效了）", CVAR_FLAGS);
    DisplayDamageMessage = CreateConVar("l4d_cloud_message_enabled", "1", "0 - 禁用;1 - 小HUD的提示;2 - 大HUD的提示;3 - 聊天通知 ", CVAR_FLAGS);
    CloudShake = CreateConVar("l4d_cloud_shake_enabled", "1", " 是否开起烟雾受伤后轻微抖动？0或1 ", CVAR_FLAGS);
    CloudBlocksRevive = CreateConVar("l4d_cloud_blocks_revive", "0", "Enable/Disable the Cloud Damage Stopping Reviving 烟雾中是否允许打包？ 0或1 ", CVAR_FLAGS);
    meleeentinfo = FindSendPropInfo("CTerrorPlayer", "m_iShovePenalty");
    propinfoghost = FindSendPropInfo("CTerrorPlayer", "m_isGhost");
    g_fCloudHrutFreq = 1.0;     // 产生毒雾时间频率
    
	// 粉碎
	hSmasherEnabled = CreateConVar("st_smasher", "1", "粉碎 Tank是否启用？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hSmasherExtraHealth = CreateConVar("st_smasher_extra_health", "50000", "粉碎 Tank的生命值",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hSmasherSpeed = CreateConVar("st_smasher_speed", "0.55", "粉碎 Tank移动速度",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,2.0);
	hSmasherThrow = CreateConVar("st_smasher_throw", "30.0", "粉碎 Tank投石冷却间隔",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,999.0);
	hSmasherFireImmunity = CreateConVar("st_smasher_fire_immunity", "1", "粉碎 Tank是否免疫火？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hSmasherMaimDamage = CreateConVar("st_smasher_maim_damage", "1", "粉碎机坦克致残的攻击将受害者的健康这一数额",FCVAR_PLUGIN|FCVAR_NOTIFY,true,1.0,true,99.0);
	hSmasherCrushDamage = CreateConVar("st_smasher_crush_damage", "1000", "粉碎机坦克爪攻击的伤害.",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1000.0);
	hSmasherRemoveBody = CreateConVar("st_smasher_remove_body", "1", "粉碎机坦克碾压攻击将删除幸存者死亡的身体吗?",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	// 瞬移
	hWarpEnabled = CreateConVar("st_warp", "1", "瞬移 Tank是否启用？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hWarpExtraHealth = CreateConVar("st_warp_extra_health", "50000", "瞬移 Tank额外的生命值",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hWarpSpeed = CreateConVar("st_warp_speed", "1.30", "瞬移 Tank移动速度",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,2.0);
	hWarpThrow = CreateConVar("st_warp_throw", "1.0", "瞬移 Tank投石冷却间隔",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,999.0);
	hWarpFireImmunity = CreateConVar("st_warp_fire_immunity", "1", "瞬移 Tank是否免疫火？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hWarpTeleportDelay = CreateConVar("st_warp_teleport_delay", "2", "瞬移坦克延迟时间间隔.",FCVAR_PLUGIN|FCVAR_NOTIFY,true,1.0,true,60.0);
	// 陨石
	hMeteorEnabled = CreateConVar("st_meteor", "1", "陨石 Tank是否启用？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hMeteorExtraHealth = CreateConVar("st_meteor_extra_health", "50000", "陨石  Tank额外的生命值",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hMeteorSpeed = CreateConVar("st_meteor_speed", "1.30", "陨石  Tank移动速度",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,2.0);
	hMeteorThrow = CreateConVar("st_meteor_throw", "5.0", "陨石  Tank投石冷却间隔",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,999.0);
	hMeteorFireImmunity = CreateConVar("st_meteor_fire_immunity", "1", "陨石 Tank是否免疫火？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hMeteorStormDelay = CreateConVar("st_meteor_storm_delay", "0.8", "流星坦克流星雨延迟时间间隔",FCVAR_PLUGIN|FCVAR_NOTIFY,true,1.0,true,60.0);
	hMeteorStormDamage = CreateConVar("st_meteor_storm_damage", "40.0", "流行伤害",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1000.0);
	// 酸液
	hSpitterEnabled = CreateConVar("st_spitter", "1", "Spitter Tank是否启用？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hSpitterExtraHealth = CreateConVar("st_spitter_extra_health", "50000", "Spitter Tank额外的生命值",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hSpitterSpeed = CreateConVar("st_spitter_speed", "1.30", "Spitter Tank移动速度",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,2.0);
	hSpitterThrow = CreateConVar("st_spitter_throw", "1.0", "Spitter Tank投石冷却间隔",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,999.0);
	hSpitterFireImmunity = CreateConVar("st_spitter_fire_immunity", "1", "Spitter Tank是否免疫火？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	iShowSpitterTimes = 3;	  // 左键几次出一次酸液
	// 治愈
	hHealEnabled = CreateConVar("st_heal", "1", "治愈 Tank是否启用？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hHealExtraHealth = CreateConVar("st_heal_extra_health", "50000", "治愈 Tank额外的生命值",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hHealSpeed = CreateConVar("st_heal_speed", "1.27", "治愈 Tank移动速度",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,2.0);
	hHealThrow = CreateConVar("st_heal_throw", "15.0", "治愈 Tank投石冷却间隔",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,999.0);
	hHealFireImmunity = CreateConVar("st_heal_fire_immunity", "1", "治愈 Tank是否免疫火？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hHealHealthCommons = CreateConVar("st_heal_health_commons", "0.5", "坦克治疗感染者每秒血量百分比",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1000.0);
	hHealHealthSpecials = CreateConVar("st_heal_health_specials", "0.02", "坦克治疗特殊感染者每秒血量百分比",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1000.0);
	hHealHealthTanks = CreateConVar("st_heal_health_tanks", "0.01", "坦克治疗每秒血量百分比",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1000.0);
	hHealDistance = CreateConVar("st_heal_distance", "500", "治愈Tank治愈距离",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	// 烈焰
	hFireEnabled = CreateConVar("st_fire", "1", "烈焰 Tank是否启用？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hFireExtraHealth = CreateConVar("st_fire_extra_health", "50000", "烈焰 Tank额外的生命值",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hFireSpeed = CreateConVar("st_fire_speed", "1.2", "烈焰 Tank移动速度",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,2.0);
	hFireThrow = CreateConVar("st_fire_throw", "6.0", "烈焰 Tank投石冷却间隔",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,999.0);
	hFireFireImmunity = CreateConVar("st_fire_fire_immunity", "1", "烈焰 Tank是否免疫火？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	// 冰霜
	hIceEnabled = CreateConVar("st_ice", "1", "冰霜 Tank是否启用？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hIceExtraHealth = CreateConVar("st_ice_extra_health", "50000", "冰霜 Tank额外的生命值",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hIceSpeed = CreateConVar("st_ice_speed", "0.70", "冰霜 Tank移动速度",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,2.0);
	hIceThrow = CreateConVar("st_ice_throw", "5.0", "冰霜 Tank投石冷却间隔",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,999.0);
	hIceFireImmunity = CreateConVar("st_ice_fire_immunity", "1", "冰霜 Tank是否免疫火？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	fIceNotMoveTimes = 2.0; // 冰冻时间
	// 猴子
	hJockeyEnabled = CreateConVar("st_jockey", "0", "Jockey Tank是否启用？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hJockeyExtraHealth = CreateConVar("st_jockey_extra_health", "50000", "Jockey Tank额外的生命值",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hJockeySpeed = CreateConVar("st_jockey_speed", "1.2", "Jockey Tank移动速度",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,2.0);
	hJockeyThrow = CreateConVar("st_jockey_throw", "5.5", "Jockey Tank抛出Jockey 间隔时间",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,999.0);
	hJockeyFireImmunity = CreateConVar("st_jockey_fire_immunity", "1", "Jockey Tank是否免疫火？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	// 幽灵
	hGhostEnabled = CreateConVar("st_ghost", "1", "隐身 Tank是否启用？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hGhostExtraHealth = CreateConVar("st_ghost_extra_health", "50000", "隐身 Tank额外的生命值",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hGhostSpeed = CreateConVar("st_ghost_speed", "1.50", "隐身 Tank移动速度",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,2.0);
	hGhostThrow = CreateConVar("st_ghost_throw", "5.0", "隐身 Tank投石冷却间隔",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,999.0);
	hGhostFireImmunity = CreateConVar("st_ghost_fire_immunity", "1", "隐身 Tank是否免疫火？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hGhostDisarm = CreateConVar("st_ghost_disarm", "1", "幽灵坦克的武装攻击的近战幸存者有机会吗?",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
    iGhostRadiiValue = 1000;    // 身边多大范围特感隐身
    iMoveGhostBeginTimes = 50;// 隐身蓄力开始
    iMoveGhostEndTimes = 5;// 现身蓄力结束
	// 闪电
	hShockEnabled = CreateConVar("st_shock", "1", "闪电 Tank是否启用？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hShockExtraHealth = CreateConVar("st_shock_extra_health", "50000", "闪电 Tank额外的生命值",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hShockSpeed = CreateConVar("st_shock_speed", "1.20", "闪电 Tank移动速度",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,2.0);
	hShockThrow = CreateConVar("st_shock_throw", "10.0", "闪电 Tank投石冷却间隔",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,999.0);
	hShockFireImmunity = CreateConVar("st_shock_fire_immunity", "1", "闪电 Tank是否免疫火？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hShockStunDamage = CreateConVar("st_shock_stun_damage", "50", "闪电坦克眩晕伤害",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1000.0);
	hShockStunMovement = CreateConVar("st_shock_stun_movement", "0.5", "闪电坦克眩晕幸存者的速度减少量",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	g_fSkillViewTime = 6.0;// 眩晕时间
    g_iSkillViewTime = 6;
	
	// 女巫
	hWitchEnabled = CreateConVar("st_witch", "1", "Witch Tank是否启用？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hWitchExtraHealth = CreateConVar("st_witch_extra_health", "50000", "Witch Tank额外的生命值",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hWitchSpeed = CreateConVar("st_witch_speed", "1.50", "Witch Tank移动速度",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,2.0);
	hWitchThrow = CreateConVar("st_witch_throw", "7.0", "Witch Tank投石冷却间隔",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,999.0);
	hWitchFireImmunity = CreateConVar("st_witch_fire_immunity", "1", "Witch Tank是否免疫火？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hWitchMaxWitches = CreateConVar("st_witch_max_witches", "3", "的最大数量的从普通感染的女巫坦克的女巫转换",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,100.0);
	fWitchSpawnTime = 15.0;	 // 产生妹子时间间隔
    fWitchSpawnDistance = 100.0;
	// 护盾
	hShieldEnabled = CreateConVar("st_shield", "1", "护盾 Tank是否启用？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hShieldExtraHealth = CreateConVar("st_shield_extra_health", "30000", "护盾 Tank额外的生命值",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hShieldSpeed = CreateConVar("st_shield_speed", "0.90", "护盾 Tank移动速度",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,2.0);
	hShieldThrow = CreateConVar("st_shield_throw", "10.0", "护盾 抛出瓦斯罐间隔时间.",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,999.0);
	hShieldFireImmunity = CreateConVar("st_shield_fire_immunity", "1", "护盾 Tank是否免疫火？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hShieldShieldsDownInterval = CreateConVar("st_shield_shields_down_interval", "20.0", "破护盾后恢复时间",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.1,true,60.0);
	// 神行
	hCobaltEnabled = CreateConVar("st_cobalt", "1", "神行 Tank是否启用？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hCobaltExtraHealth = CreateConVar("st_cobalt_extra_health", "50000", "神行 Tank额外的生命值",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hCobaltSpeed = CreateConVar("st_cobalt_speed", "1.0", "神行 Tank移动速度",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,2.0);
	hCobaltThrow = CreateConVar("st_cobalt_throw", "99.0", "神行 Tank投石冷却间隔",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,999.0);
	hCobaltFireImmunity = CreateConVar("st_cobalt_fire_immunity", "1", "神行 Tank是否免疫火？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hCobaltSpecialSpeed = CreateConVar("st_cobalt_Special_speed", "3.1", "模糊坦克运动值时，加速冲向一个幸存者",FCVAR_PLUGIN|FCVAR_NOTIFY,true,1.0,true,5.0);
    iMoveCobaltBeginTimes = 50;// 瞬移蓄力时间
    iMoveCobaltEndTimes = 5;// 瞬移蓄力时间
	// 跳跳
	hJumperEnabled = CreateConVar("st_jumper", "1", "跳跳 Tank是否启用？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hJumperExtraHealth = CreateConVar("st_jumper_extra_health", "50000", "跳跳 Tank额外的生命值",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hJumperSpeed = CreateConVar("st_jumper_speed", "1.20", "跳跳 Tank移动速度",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,2.0);
	hJumperThrow = CreateConVar("st_jumper_throw", "99.0", "跳跳 Tank投石冷却间隔",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,999.0);
	hJumperFireImmunity = CreateConVar("st_jumper_fire_immunity", "1", "跳跳 Tank是否免疫火？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hJumperJumpDelay = CreateConVar("st_jumper_jump_delay", "2.8", "的跳线坦克延迟时间间隔跳了",FCVAR_PLUGIN|FCVAR_NOTIFY,true,1.0,true,60.0);
	// 磁力
	hGravityEnabled = CreateConVar("st_gravity", "1", "磁力 Tank是否启用？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hGravityExtraHealth = CreateConVar("st_gravity_extra_health", "50000", "磁力 Tank额外的生命值",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hGravitySpeed = CreateConVar("st_gravity_speed", "0.85", "磁力 Tank移动速度",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,2.0);
	hGravityThrow = CreateConVar("st_gravity_throw", "10.0", "磁力 Tank投石冷却间隔",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,999.0);
	hGravityFireImmunity = CreateConVar("st_gravity_fire_immunity", "1", "磁力 Tank是否免疫火？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hGravityPullForce = CreateConVar("st_gravity_pull_force", "-100.0", "负数越高磁力越大",FCVAR_PLUGIN|FCVAR_NOTIFY,true,-200.0,true,0.0);
	g_iGravityRadiiYard = 750;    // 磁力范围
    g_fGravityFreqTimes = 0.2;        // 频率
    g_fGravityFreqYard = 1.0;       // 吸附1米
	// 胆汁
	hBoomerEnabled = CreateConVar("st_boomer", "1", "启用胆汁Tank吗?",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hBoomerExtraHealth = CreateConVar("st_boomer_extra_health", "50000.0", "胆汁 Tank的生命值",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hBoomerSpeed = CreateConVar("st_boomer_speed", "1.50", "胆汁 Tank移动速度",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,2.0);
	hBoomerThrow = CreateConVar("st_boomer_throw", "1.0", "胆汁 Tank投石冷却间隔",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,999.0);
	hBoomerFireImmunity = CreateConVar("st_boomer_fire_immunity", "1", "胆汁 Tank是否免疫火？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	iShowBoomerTimes = 3;	  // 左键几次出一次胆汁
	// 熔岩
	hRongYanEnabled = CreateConVar("st_rongyan", "1", "启用熔岩Tank吗?",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hRongYanExtraHealth = CreateConVar("st_rongyan_extra_health", "65000.0", "熔岩 Tank的生命值",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hRongYanSpeed = CreateConVar("st_rongyan_speed", "1.25", "熔岩 Tank移动速度",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,2.0);
	hRongYanThrow = CreateConVar("st_rongyan_throw", "5.0", "熔岩 Tank投石冷却间隔",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,999.0);
	hRongYanFireImmunity = CreateConVar("st_rongyan_fire_immunity", "1", "熔岩 Tank是否免疫火？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	sm_lastboss_tankry_hxdmg			= CreateConVar("sm_lastboss_tankry_hxdmg", "10", "红血攻击造成的附加伤害", CVAR_FLAGS);
	// 重力
	hZhongLiEnabled = CreateConVar("st_zhongli", "1", "启用重力Tank吗?",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hZhongLiExtraHealth = CreateConVar("st_zhongli_extra_health", "50000.0", "重力 Tank的生命值",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hZhongLiSpeed = CreateConVar("st_zhongli_speed", "1.25", "重力 Tank移动速度",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,2.0);
	hZhongLiThrow = CreateConVar("st_zhongli_throw", "5.0", "重力 Tank投石冷却间隔",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,999.0);
	hZhongLiFireImmunity = CreateConVar("st_zhongli_fire_immunity", "1", "重力 Tank是否免疫火？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	sm_lastboss_gravityinterval		= CreateConVar("sm_lastboss_gravityinterval", "1.0", "重力技能击中后重力持续的时间", CVAR_FLAGS);
    fZhongLiClawValue = 0.03;    // 重力修改值
    
	// 恐惧
	hKongJuEnabled = CreateConVar("st_kongju", "1", "启用恐惧Tank吗?",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hKongJuExtraHealth = CreateConVar("st_kongju_extra_health", "65000.0", "恐惧 Tank的生命值",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hKongJuSpeed = CreateConVar("st_kongju_speed", "1.25", "恐惧 Tank移动速度",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,2.0);
	hKongJuThrow = CreateConVar("st_kongju_throw", "5.0", "恐惧 Tank投石冷却间隔",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,999.0);
	hKongJuFireImmunity = CreateConVar("st_kongju_fire_immunity", "1", "恐惧 Tank是否免疫火？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	sm_lastboss_dreadinterval		= CreateConVar("sm_lastboss_dreadinterval", "9.0", "致盲技能的持续时间", CVAR_FLAGS);
	sm_lastboss_dreadrate			= CreateConVar("sm_lastboss_dreadrate", "252", "致盲技能致盲程度", CVAR_FLAGS);
	// 地震
	hDiZhenEnabled = CreateConVar("st_dizhen", "1", "启用 地震 Tank吗?",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hDiZhenExtraHealth = CreateConVar("st_dizhen_extra_health", "65000.0", "地震 Tank的生命值",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hDiZhenSpeed = CreateConVar("st_dizhen_speed", "1.30", "地震 Tank移动速度",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,2.0);
	hDiZhenThrow = CreateConVar("st_dizhen_throw", "5.0", "地震 Tank投石冷却间隔",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,999.0);
	hDiZhenFireImmunity = CreateConVar("st_dizhen_fire_immunity", "1", "地震 Tank是否免疫火？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	sm_lastboss_quake_radius			= CreateConVar("sm_lastboss_quake_radius", "800.0", "地震技能的半径", CVAR_FLAGS);
	sm_lastboss_quake_force			= CreateConVar("sm_lastboss_quake_force", "400.0", "地震技能的威力", CVAR_FLAGS);
	// 游击
	hYouJiEnabled = CreateConVar("st_youji", "1", "启用 游击 Tank吗?",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hYouJiExtraHealth = CreateConVar("st_youji_extra_health", "60000.0", "游击 Tank的生命值",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hYouJiSpeed = CreateConVar("st_youji_speed", "2.90", "游击 Tank移动速度",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,2.0);
	hYouJiThrow = CreateConVar("st_youji_throw", "5.0", "游击 Tank投石冷却间隔",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,999.0);
	hYouJiFireImmunity = CreateConVar("st_youji_fire_immunity", "1", "游击 Tank是否免疫火？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);	
	// 分身
	hDoubleEnabled = CreateConVar("st_double", "1", "启用 分身 Tank吗?",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hDoubleExtraHealth = CreateConVar("st_double_extra_health", "30000.0", "分身 Tank的生命值",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hDoubleSpeed = CreateConVar("st_double_speed", "1.10", "分身 Tank移动速度",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,2.0);
	hDoubleThrow = CreateConVar("st_double_throw", "5.0", "分身 Tank投石冷却间隔",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,999.0);
	hDoubleFireImmunity = CreateConVar("st_double_fire_immunity", "1", "分身 Tank是否免疫火？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	iDoubleTankCounts = 3;  // 分身数量
	// 疯狂暴走
	hAdrenalEnabled = CreateConVar("st_adrenal", "0", "启用 疯狂暴走 Tank吗?",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hAdrenalExtraHealth = CreateConVar("st_adrenal_extra_health", "50000.0", "疯狂暴走 Tank的生命值",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hAdrenalSpeed = CreateConVar("st_adrenal_speed", "1.20", "疯狂暴走 Tank移动速度",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,2.0);
	hAdrenalThrow = CreateConVar("st_adrenal_throw", "0.5", "疯狂暴走 Tank投石冷却间隔",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,999.0);
	hAdrenalFireImmunity = CreateConVar("st_adrenal_fire_immunity", "1", "疯狂暴走 Tank是否免疫火？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	// 忍者
	hRenZheEnabled = CreateConVar("st_renzhe", "1", "启用 忍者 Tank吗?",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hRenZheExtraHealth = CreateConVar("st_renzhe_extra_health", "50000.0", "忍者 Tank的生命值",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	hRenZheSpeed = CreateConVar("st_renzhe_speed", "1.0", "忍者 Tank移动速度",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,2.0);
	hRenZheThrow = CreateConVar("st_renzhe_throw", "5.5", "忍者 Tank投石冷却间隔",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,999.0);
	hRenZheFireImmunity = CreateConVar("st_renzhe_fire_immunity", "1", "忍者 Tank是否免疫火？",FCVAR_PLUGIN|FCVAR_NOTIFY,true,0.0,true,1.0);
	// 句柄值获取
	bSuperTanksEnabled = GetConVarBool(hSuperTanksEnabled);
	//bDisplayHealthCvar = GetConVarBool(hDisplayHealthCvar);
	//iWave1Cvar = GetConVarInt(hWave1Cvar);
	//iWave2Cvar = GetConVarInt(hWave2Cvar);
	//iWave3Cvar = GetConVarInt(hWave3Cvar);
	//bFinaleOnly = GetConVarBool(hFinaleOnly);
	//bDefaultTanks = GetConVarBool(hDefaultTanks);
	//bDefaultOverride = GetConVarBool(hDefaultOverride);

	bTankEnabled[1] = GetConVarBool(hSpawnEnabled);
	bTankEnabled[2] = GetConVarBool(hSmasherEnabled);
	bTankEnabled[3] = GetConVarBool(hWarpEnabled);
	bTankEnabled[4] = GetConVarBool(hMeteorEnabled);
	bTankEnabled[5] = GetConVarBool(hSpitterEnabled);
	bTankEnabled[6] = GetConVarBool(hHealEnabled);
	bTankEnabled[7] = GetConVarBool(hFireEnabled);
	bTankEnabled[8] = GetConVarBool(hIceEnabled);
	bTankEnabled[9] = GetConVarBool(hJockeyEnabled);
	bTankEnabled[10] = GetConVarBool(hGhostEnabled);
	bTankEnabled[11] = GetConVarBool(hShockEnabled);
	bTankEnabled[12] = GetConVarBool(hWitchEnabled);
	bTankEnabled[13] = GetConVarBool(hShieldEnabled);
	bTankEnabled[14] = GetConVarBool(hCobaltEnabled);
	bTankEnabled[15] = GetConVarBool(hJumperEnabled);
	bTankEnabled[16] = GetConVarBool(hGravityEnabled);
	bTankEnabled[17] = GetConVarBool(hBoomerEnabled);
	bTankEnabled[18] = GetConVarBool(hRongYanEnabled);
	bTankEnabled[19] = GetConVarBool(hZhongLiEnabled);
	bTankEnabled[20] = GetConVarBool(hKongJuEnabled);
	bTankEnabled[21] = GetConVarBool(hDiZhenEnabled);
	bTankEnabled[22] = GetConVarBool(hYouJiEnabled);
	bTankEnabled[23] = GetConVarBool(hDoubleEnabled);
	bTankEnabled[24] = GetConVarBool(hAdrenalEnabled);
	bTankEnabled[25] = GetConVarBool(hRenZheEnabled);

	iTankExtraHealth[0] = 6000;
	iTankExtraHealth[1] = GetConVarInt(hSpawnExtraHealth);
	iTankExtraHealth[2] = GetConVarInt(hSmasherExtraHealth);
	iTankExtraHealth[3] = GetConVarInt(hWarpExtraHealth);
	iTankExtraHealth[4] = GetConVarInt(hMeteorExtraHealth);
	iTankExtraHealth[5] = GetConVarInt(hSpitterExtraHealth);
	iTankExtraHealth[6] = GetConVarInt(hHealExtraHealth);
	iTankExtraHealth[7] = GetConVarInt(hFireExtraHealth);
	iTankExtraHealth[8] = GetConVarInt(hIceExtraHealth);
	iTankExtraHealth[9] = GetConVarInt(hJockeyExtraHealth);
	iTankExtraHealth[10] = GetConVarInt(hGhostExtraHealth);
	iTankExtraHealth[11] = GetConVarInt(hShockExtraHealth);
	iTankExtraHealth[12] = GetConVarInt(hWitchExtraHealth);
	iTankExtraHealth[13] = GetConVarInt(hShieldExtraHealth);
	iTankExtraHealth[14] = GetConVarInt(hCobaltExtraHealth);
	iTankExtraHealth[15] = GetConVarInt(hJumperExtraHealth);
	iTankExtraHealth[16] = GetConVarInt(hGravityExtraHealth);
	iTankExtraHealth[17] = GetConVarInt(hBoomerExtraHealth);
	iTankExtraHealth[18] = GetConVarInt(hRongYanExtraHealth);
	iTankExtraHealth[19] = GetConVarInt(hZhongLiExtraHealth);
	iTankExtraHealth[20] = GetConVarInt(hKongJuExtraHealth);
	iTankExtraHealth[21] = GetConVarInt(hDiZhenExtraHealth);
	iTankExtraHealth[22] = GetConVarInt(hYouJiExtraHealth);
	iTankExtraHealth[23] = GetConVarInt(hDoubleExtraHealth);
	iTankExtraHealth[24] = GetConVarInt(hAdrenalExtraHealth);
	iTankExtraHealth[25] = GetConVarInt(hRenZheExtraHealth);

	//flTankSpeed[0] = GetConVarFloat(hDefaultSpeed);
	flTankSpeed[1] = GetConVarFloat(hSpawnSpeed);
	flTankSpeed[2] = 0.55;//GetConVarFloat(hSmasherSpeed);
	flTankSpeed[3] = GetConVarFloat(hWarpSpeed);
	flTankSpeed[4] = GetConVarFloat(hMeteorSpeed);
	flTankSpeed[5] = GetConVarFloat(hSpitterSpeed);
	flTankSpeed[6] = GetConVarFloat(hHealSpeed);
	flTankSpeed[7] = GetConVarFloat(hFireSpeed);
	flTankSpeed[8] = GetConVarFloat(hIceSpeed);
	flTankSpeed[9] = GetConVarFloat(hJockeySpeed);
	flTankSpeed[10] = GetConVarFloat(hGhostSpeed);
	flTankSpeed[11] = GetConVarFloat(hShockSpeed);
	flTankSpeed[12] = GetConVarFloat(hWitchSpeed);
	flTankSpeed[13] = GetConVarFloat(hShieldSpeed);
	flTankSpeed[14] = 0.5;//GetConVarFloat(hCobaltSpeed);
	flTankSpeed[15] = GetConVarFloat(hJumperSpeed);
	flTankSpeed[16] = GetConVarFloat(hGravitySpeed);
	flTankSpeed[17] = GetConVarFloat(hBoomerSpeed);
	flTankSpeed[18] = GetConVarFloat(hRongYanSpeed);
	flTankSpeed[19] = GetConVarFloat(hZhongLiSpeed);
	flTankSpeed[20] = GetConVarFloat(hKongJuSpeed);
	flTankSpeed[21] = GetConVarFloat(hDiZhenSpeed);
	flTankSpeed[22] = GetConVarFloat(hYouJiSpeed);
	flTankSpeed[23] = GetConVarFloat(hDoubleSpeed);
	flTankSpeed[24] = GetConVarFloat(hAdrenalSpeed);
	flTankSpeed[25] = GetConVarFloat(hRenZheSpeed);

	//flTankThrow[0] = GetConVarFloat(hDefaultThrow);
	flTankThrow[1] = GetConVarFloat(hSpawnThrow);
	flTankThrow[2] = GetConVarFloat(hSmasherThrow);
	flTankThrow[3] = GetConVarFloat(hWarpThrow);
	flTankThrow[4] = GetConVarFloat(hMeteorThrow);
	flTankThrow[5] = GetConVarFloat(hSpitterThrow);
	flTankThrow[6] = GetConVarFloat(hHealThrow);
	flTankThrow[7] = GetConVarFloat(hFireThrow);
	flTankThrow[8] = GetConVarFloat(hIceThrow);
	flTankThrow[9] = GetConVarFloat(hJockeyThrow);
	flTankThrow[10] = GetConVarFloat(hGhostThrow);
	flTankThrow[11] = GetConVarFloat(hShockThrow);
	flTankThrow[12] = GetConVarFloat(hWitchThrow);
	flTankThrow[13] = GetConVarFloat(hShieldThrow);
	flTankThrow[14] = GetConVarFloat(hCobaltThrow);
	flTankThrow[15] = GetConVarFloat(hJumperThrow);
	flTankThrow[16] = GetConVarFloat(hGravityThrow);
	flTankThrow[17] = GetConVarFloat(hBoomerThrow);
	flTankThrow[18] = GetConVarFloat(hRongYanThrow);
	flTankThrow[19] = GetConVarFloat(hZhongLiThrow);
	flTankThrow[20] = GetConVarFloat(hKongJuThrow);
	flTankThrow[21] = GetConVarFloat(hDiZhenThrow);
	flTankThrow[22] = GetConVarFloat(hYouJiThrow);
	flTankThrow[23] = GetConVarFloat(hDoubleThrow);
	flTankThrow[24] = GetConVarFloat(hAdrenalThrow);
	flTankThrow[25] = GetConVarFloat(hRenZheThrow);

	//bTankFireImmunity[0] = GetConVarBool(hDefaultFireImmunity);
	bTankFireImmunity[1] = GetConVarBool(hSpawnFireImmunity);
	bTankFireImmunity[2] = GetConVarBool(hSmasherFireImmunity);
	bTankFireImmunity[3] = GetConVarBool(hWarpFireImmunity);
	bTankFireImmunity[4] = GetConVarBool(hMeteorFireImmunity);
	bTankFireImmunity[5] = GetConVarBool(hSpitterFireImmunity);
	bTankFireImmunity[6] = GetConVarBool(hHealFireImmunity);
	bTankFireImmunity[7] = GetConVarBool(hFireFireImmunity);
	bTankFireImmunity[8] = GetConVarBool(hIceFireImmunity);
	bTankFireImmunity[9] = GetConVarBool(hJockeyFireImmunity);
	bTankFireImmunity[10] = GetConVarBool(hGhostFireImmunity);
	bTankFireImmunity[11] = GetConVarBool(hShockFireImmunity);
	bTankFireImmunity[12] = GetConVarBool(hWitchFireImmunity);
	bTankFireImmunity[13] = GetConVarBool(hShieldFireImmunity);
	bTankFireImmunity[14] = GetConVarBool(hCobaltFireImmunity);
	bTankFireImmunity[15] = GetConVarBool(hJumperFireImmunity);
	bTankFireImmunity[16] = GetConVarBool(hGravityFireImmunity);
	bTankFireImmunity[17] = GetConVarBool(hBoomerFireImmunity);
	bTankFireImmunity[18] = GetConVarBool(hRongYanFireImmunity);
	bTankFireImmunity[19] = GetConVarBool(hZhongLiFireImmunity);
	bTankFireImmunity[20] = GetConVarBool(hKongJuFireImmunity);
	bTankFireImmunity[21] = GetConVarBool(hDiZhenFireImmunity);
	bTankFireImmunity[22] = GetConVarBool(hYouJiFireImmunity);
	bTankFireImmunity[23] = GetConVarBool(hDoubleFireImmunity);
	bTankFireImmunity[24] = GetConVarBool(hAdrenalFireImmunity);
	bTankFireImmunity[25] = GetConVarBool(hRenZheFireImmunity);

	iSpawnCommonAmount = GetConVarInt(hSpawnCommonAmount);
	iSpawnCommonInterval = GetConVarInt(hSpawnCommonInterval);
	iSmasherMaimDamage = GetConVarInt(hSmasherMaimDamage);
	iSmasherCrushDamage = GetConVarInt(hSmasherCrushDamage);
	bSmasherRemoveBody = GetConVarBool(hSmasherRemoveBody);
	iWarpTeleportDelay = GetConVarInt(hWarpTeleportDelay);
	fMeteorStormDelay = GetConVarFloat(hMeteorStormDelay);
	flMeteorStormDamage = GetConVarFloat(hMeteorStormDamage);
	// 治愈
	fHealHealthCommons = GetConVarFloat(hHealHealthCommons);
	fHealHealthSpecials = GetConVarFloat(hHealHealthSpecials);
	fHealHealthTanks = GetConVarFloat(hHealHealthTanks);
	iHealTankDistance = GetConVarInt(hHealDistance);
	
	bGhostDisarm = GetConVarBool(hGhostDisarm);
	iShockStunDamage = GetConVarInt(hShockStunDamage);
	flShockStunMovement = GetConVarFloat(hShockStunMovement);
	iWitchMaxWitches = GetConVarInt(hWitchMaxWitches);
	flShieldShieldsDownInterval = GetConVarFloat(hShieldShieldsDownInterval);
	flCobaltSpecialSpeed = GetConVarFloat(hCobaltSpecialSpeed);
	fJumperJumpDelay = GetConVarFloat(hJumperJumpDelay);
	flGravityPullForce = GetConVarFloat(hGravityPullForce);


	/* Event hook */
	HookEvent("ability_use", Ability_Use);
	HookEvent("round_start", Event_Round_Start);
	HookEvent("tank_spawn", Event_Tank_Spawn);
	HookEvent("tank_frustrated", Event_Tank_Frustrated);
	HookEvent("player_death", Event_Player_Death);
	HookEvent("player_hurt", Event_Player_Hurt);
	HookEvent("player_incapacitated", Event_Player_Hurt);
	   
	
	HookEvent("player_jump_apex", Event_Player_Jump_Apex);
	HookEvent("player_jump", Event_Player_Jump, EventHookMode_Pre);
	
	HookEvent("player_footstep", Event_Player_Foot);
	HookEvent("player_team", Event_Player_Team);
	HookEvent("player_spawn", Event_PlayerSpawn);// 玩家创建，技能初始化
	
	RegConsoleCmd("sm_tank", SmSetTank);
	
	CreateTimer(0.1,TimerUpdate01, _, TIMER_REPEAT);
	CreateTimer(1.0,TimerUpdate1, _, TIMER_REPEAT);		//屏蔽插件解除32人问题，我也不知道为什么作者为什么会限制32人
	
	g_iLaggedMovementO	=	FindSendPropInfo("CTerrorPlayer","m_flLaggedMovementValue");
		
	InitSDKCalls();
	//InitStartUp();
	
	//AutoExecConfig(true, "l4d2_lastboss_yd");
}

//=============================
// StartUp
//=============================
InitSDKCalls()
{
	new Handle:ConfigFile = LoadGameConfigFile("supertanks");
	new Handle:MySDKCall = INVALID_HANDLE;

	if(ConfigFile == INVALID_HANDLE)
	{
		ThrowError("Could not load gamedata/supertanks.txt");
	}
	/////////////
	//SpitBurst//
	/////////////
	StartPrepSDKCall(SDKCall_Player);
	PrepSDKCall_SetFromConf(ConfigFile, SDKConf_Signature, "CSpitterProjectile_Detonate");
	PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);
	MySDKCall = EndPrepSDKCall();
	if (MySDKCall == INVALID_HANDLE)
	{
		SetFailState("Cant initialize CSpitterProjectile_Detonate SDKCall");
	}
	SDKSpitBurst = CloneHandle(MySDKCall, SDKSpitBurst);

	/////////////////
	//VomitOnPlayer//
	/////////////////
	StartPrepSDKCall(SDKCall_Player);
	PrepSDKCall_SetFromConf(ConfigFile, SDKConf_Signature, "CTerrorPlayer_OnVomitedUpon");
	PrepSDKCall_AddParameter(SDKType_CBasePlayer, SDKPass_Pointer);
	PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);
	MySDKCall = EndPrepSDKCall();
	if (MySDKCall == INVALID_HANDLE)
	{
		SetFailState("Cant initialize CTerrorPlayer_OnVomitedUpon SDKCall");
	}
	SDKVomitOnPlayer = CloneHandle(MySDKCall, SDKVomitOnPlayer);

	CloseHandle(ConfigFile);
	CloseHandle(MySDKCall);
}
stock SDKCallSpitBurst(client)
{
	SDKCall(SDKSpitBurst, client, true);
}
stock SDKCallVomitOnPlayer(victim, attacker)
{
	SDKCall(SDKVomitOnPlayer, victim, attacker, true);
}
InitStartUp()
{
	if (bSuperTanksEnabled)
	{
		decl String:gamemode[24];
		GetConVarString(FindConVar("mp_gamemode"), gamemode, sizeof(gamemode));
	   	if (!StrEqual(gamemode, "coop", false) && !StrEqual(gamemode, "realism", false))
		{
			PrintToServer("[SuperTanks] This plugin is only compatible in Coop or Realism gamemodes.");
			PrintToServer("[SuperTanks] Plugin Disabled.");
			SetConVarBool(hSuperTanksEnabled, false);		
		}
	}
}

/******************************************************
*	Initial functions
*******************************************************/
InitPrecache()
{
	/* Precache models */
	PrecacheModel(ENTITY_PROPANE, true);
	PrecacheModel(ENTITY_GASCAN, true);

	/* Precache sounds */
	PrecacheSound(SOUND_EXPLODE, true);
	PrecacheSound(SOUND_SPAWN, true);
	PrecacheSound(SOUND_BCLAW, true);
	PrecacheSound(SOUND_GCLAW, true);
	PrecacheSound(SOUND_DCLAW, true);
	PrecacheSound(SOUND_QUAKE, true);
	PrecacheSound(SOUND_STEEL, true);
	PrecacheSound(SOUND_CHANGE, true);
	PrecacheSound(SOUND_HOWL, true);
	PrecacheSound(SOUND_WARP, true);

	/* Precache particles */
	//PrecacheParticle(PARTICLE_SPAWN);
	PrecacheParticle(PARTICLE_DEATH);
	PrecacheParticle(PARTICLE_THIRD);
	PrecacheParticle(PARTICLE_FORTH);
	PrecacheParticle(PARTICLE_WARP);
	// super tank
	PrecacheParticle(PARTICLE_SPAWN);
	PrecacheParticle(PARTICLE_FIRE);
	PrecacheParticle(PARTICLE_WARP);
	PrecacheParticle(PARTICLE_ICE);
	PrecacheParticle(PARTICLE_SPIT);
	PrecacheParticle(PARTICLE_SPITPROJ);
	PrecacheParticle(PARTICLE_ELEC);
	PrecacheParticle(PARTICLE_BLOOD);
	PrecacheParticle(PARTICLE_EXPLODE);
	PrecacheParticle(PARTICLE_METEOR);
	CheckModelPreCache("models/props_junk/gascan001a.mdl");
	CheckModelPreCache("models/props_junk/propanecanister001a.mdl");
	CheckModelPreCache("models/infected/witch.mdl");
	CheckModelPreCache("models/infected/witch_bride.mdl");
	CheckModelPreCache("models/props_vehicles/tire001c_car.mdl");
	CheckModelPreCache("models/props_unique/airport/atlas_break_ball.mdl");
	CheckSoundPreCache("ambient/fire/gascan_ignite1.wav");
	CheckSoundPreCache("player/charger/hit/charger_smash_02.wav");
	CheckSoundPreCache("npc/infected/action/die/male/death_42.wav");
	CheckSoundPreCache("npc/infected/action/die/male/death_43.wav");
	CheckSoundPreCache("ambient/energy/zap1.wav");
	CheckSoundPreCache("ambient/energy/zap5.wav");
	CheckSoundPreCache("ambient/energy/zap7.wav");
	CheckSoundPreCache("player/spitter/voice/warn/spitter_spit_02.wav");
	CheckSoundPreCache("player/tank/voice/growl/tank_climb_01.wav");
	CheckSoundPreCache("player/tank/voice/growl/tank_climb_02.wav");
	CheckSoundPreCache("player/tank/voice/growl/tank_climb_03.wav");
	CheckSoundPreCache("player/tank/voice/growl/tank_climb_04.wav");
}

stock CheckModelPreCache(const String:Modelfile[])
{
	if (!IsModelPrecached(Modelfile))
	{
		PrecacheModel(Modelfile, true);
		PrintToServer("[Super Tanks]Precaching Model:%s",Modelfile);
	}
}
stock CheckSoundPreCache(const String:Soundfile[])
{
	//if (!IsSoundPrecached(Soundfile)) //Removed, Function not working
	//{
		PrecacheSound(Soundfile, true);
		PrintToServer("[Super Tanks]Precaching Sound:%s",Soundfile);
	//}
}
InitData()
{
	/* Reset flags */
	for (new i = 1; i <= MaxClients; i++)
	{
		if (i > 32) { return; }
		tanktype[i] = 0;
		clientlosscount[i] = 0;
		TankAbility[i] = 0;
		Rock[i] = 0;
		PlayerSpeed[i] = 0;
		g_iPlayerMaxHealth[i] = 500;
		iMoveWarpAbleFlag[i] = 0;
		iMoveCobaltAbleFlag[i] = 0;
		iMoveGhostAbleFlag[i] = 0;
		
		bShieldDemageFlag[i] = false;
		bIsDoubleTankSpawn[i] = false;
		iShowSpitterIndex[i] = 0;
		iShowBoomerIndex[i] = 0;
		bJumperPressDelayp[i] = false;
        bRenZhePressDelayp[i] = false;
        
        iMoveCobaltBeginTimeFlag[i] = 0;
		iMoveCobaltEndTimeFlag[i] = 0;	
        
        iMoveGhostBeginTimeFlag[i] = 0;
		iMoveGhostEndTimeFlag[i] = 0;
        
        // 闪电tank属性
        g_iShockHurtFlag[i] = 0;
        g_iShockHurtTimes[i] = 0;
	}
	changehealth = 0;
	//
	iNumTanks = 0;
	
}

public OnClientPostAdminCheck(client)
{	
	TankAbility[client] = 0;
	Rock[client] = 0;
	PlayerSpeed[client] = 0;
	bShieldDemageFlag[client] = false;
}
public OnClientConnected(client)
{
	//CreateTimer(8.1, timerCheckHookClient, client, TIMER_FLAG_NO_MAPCHANGE);
}
public Action:timerCheckHookClient(Handle:timer, any:client)
{
	LoadHooks(client);
} 
LoadHooks(client)
{
	//new bool:Temp = SDKHookEx(client, SDKHook_OnTakeDamage, OnPlayerTakeDamage);
}

public OnMapStart()
{
	InitPrecache();
	InitData();	
}

public OnMapEnd()
{

}

public Action:Event_Round_Start(Handle:event, const String:name[], bool:dontBroadcast)
{
	InitData();
	CreateTimer(8.0, Timer_Tank_Select_Msg);
	new flags = GetConVarFlags(FindConVar("z_max_player_zombies"));
	SetConVarBounds(FindConVar("z_max_player_zombies"), ConVarBound_Upper, false);
	SetConVarFlags(FindConVar("z_max_player_zombies"), flags & ~FCVAR_NOTIFY);
	SetConVarInt(FindConVar("z_hunter_limit"), 5);
	SetConVarInt(FindConVar("z_jockey_limit"), 5);
	SetConVarInt(FindConVar("z_charger_limit"), 5);
	SetConVarInt(FindConVar("z_hunter_limit"), 5);
	SetConVarInt(FindConVar("z_boomer_limit"), 5);
	SetConVarInt(FindConVar("z_spitter_limit"), 5);
	
	// 模型还原
	for (new i=1; i<=MaxClients; i++)
    {		
		if(IsValidPlayer(i))
		{
			// 颜色效果去除
			SetEntProp(i, Prop_Send, "m_glowColorOverride", 0);
			SetEntProp(i, Prop_Send, "m_iGlowType", 0);
			SetEntProp(i, Prop_Send, "m_bFlashing", 0);    
		}
    }
}
public Action:Ability_Use(Handle:event, String:event_name[], bool:dontBroadcast)
{
	new client = GetClientOfUserId(GetEventInt(event,"userid"));

	if (bSuperTanksEnabled)
	{
		if (IsValidPlayer(client) && IsTank(client))
		{
			if(tanktype[client] > 0 && tanktype[client] < TANK_COUNT)
			{
				new type = tanktype[client];
				ResetInfectedAbility(client, flTankThrow[type]);
			}
		}
	}
}

public Action:Event_Player_Foot(Handle:event, const String:name[], bool:dontBroadcast)
{
	//new victim = GetClientOfUserId(GetEventInt(event, "userid"));   //
	//CPrintToChatAll("踩___%N", victim);
}
// 跳事件
public Action:Event_Player_Jump(Handle:event, const String:name[], bool:dontBroadcast)
{
	//new client = GetClientOfUserId(GetEventInt(event, "userid"));   // 
	
}
// 跳下后落地时间
public Action:Event_Player_Jump_Apex(Handle:event, const String:name[], bool:dontBroadcast)
{
	//new victim = GetClientOfUserId(GetEventInt(event, "userid"));   // 受害人	
	//CPrintToChatAll("跳_ex___%N", victim);
}

//Zoom button used (Default)
public Action:OnPlayerRunCmd(client, &buttons, &impulse, Float:vel[3], Float:angles[3], &weapon)
{   
	if((buttons & IN_ZOOM))
	{		
		if (IsTank(client) && !bIsDoubleTankSpawn[client])
		{
			switch(tanktype[client])
			{				
				// 心灵传送
				case TANK_Warp:
				{
					TeleportTank(client);
				}
				// 忍者
				case TANK_RenZhe:
				{
                    
                    if(!bRenZhePressDelayp[client])
					{
						//CPrintToChatAll("跳___%N", client);
						bRenZhePressDelayp[client] = true;
						CreateTimer(0.5, ResetRenZhePressDelay, client);						
						CreateTimer(0.1, RenZheTankTimer, client);
					}
					
				}
			}			
		}
	}
	if((buttons & IN_JUMP))
	{		
		if (IsTank(client) && !bIsDoubleTankSpawn[client])
		{
			switch(tanktype[client])
			{				
				// 跳跃
				case TANK_Jumper:
				{
					if(!bJumperPressDelayp[client])
					{
						//CPrintToChatAll("跳___%N", client);
						bJumperPressDelayp[client] = true;
						CreateTimer(0.5, ResetPressDelay, client);						
						FakeJump(client);
					}
				}
			}			
		}
	}  	
}
/******************************************************
*	坦克产生事件
*******************************************************/
public Action:Event_Tank_Spawn(Handle:event, const String:name[], bool:dontBroadcast)
{
	if(!GetConVarInt(hSuperTanksEnabled)) { return; }
	new client = GetClientOfUserId(GetEventInt(event, "userid"));
	/* Reset flags */
	clientlosscount[client] = 0;

	if(client > 0 && client < MaxClients && IsClientInGame(client) && IsValidEntity(client) && !IsFakeClient(client))
	{
		TankAbility[client] = 0;
		if(!bIsDoubleTankSpawn[client])
		{
			{
				if (tanktype[client] >= 1)	// 玩家选择tank技能
				{
					SetTankType(client, tanktype[client]);
				}
				else
				{
					new randomtank = GetRandomInt(1, TANK_COUNT); // 给予随机技能
					SetTankType(client, randomtank);
				}
			}
		}
		else
		{
			SetDoubleTankValue(client);
		}

		for(new j = 1; j <= MaxClients; j++)
		{
			if(IsClientInGame(j) && !IsFakeClient(j))
			{
				EmitSoundToClient(j, SOUND_SPAWN);  // 声音效果
			}
		}
		// 检测tank丢控制事件，创建后10秒运行执行
		if (client > 0 && client < MaxClients && IsClientInGame(client) && IsValidEntity(client) && !IsFakeClient(client))
		{
			CreateTimer(10.0, CheckFrustration, client);
		}
	}
}
/******************************************************
*	AI坦克
*******************************************************/
public Action:L4D_OnSpawnTank(const Float:vector[3], const Float:qangle[3])
{
	// 直接产生
	new random_client = GetRandomPlayer(3);
	if(IsValidPlayer(random_client, false,true))
	{
		TankSpawner(random_client);	// 指定为某个玩家
	}
	return Plugin_Continue;
}


/******************************************************
*	坦克更换控制者
*******************************************************/
public Action:Event_Tank_Frustrated(Handle:event, const String:name[], bool:dontBroadcast)
{
	new userid = GetClientOfUserId(GetEventInt(event, "userid"));
	PrintToChatAll("插件运行出错，请截图给Yd技术一夜男或曼陀罗");
	PrintToChatAll("插件运行出错，请截图给Yd技术一夜男或曼陀罗");
	PrintToChatAll("插件运行出错，请截图给Yd技术一夜男或曼陀罗");
	TankChange(userid);
}

//** a very important event! =P 重要，幸存初始化
public Event_PlayerSpawn (Handle:event, const String:name[], bool:dontBroadcast)
{
	new client=GetClientOfUserId(GetEventInt(event,"userid"));
	CreateTimer(0.2, GetMaxHealth, client);	
}
// 获取出生时血量
public Action:GetMaxHealth(Handle:timer, any:client)
{
	if(IsValidPlayer(client))
	{
		g_iPlayerMaxHealth[client] = GetEntProp(client, Prop_Data, "m_iHealth");
		//PrintToChat(client, "最大生命%d", g_iPlayerMaxHealth[client]);
	}
}
/******************************************************
*	玩家/坦克死亡事件
*******************************************************/
public Action:Event_Player_Death(Handle:event, const String:name[], bool:dontBroadcast)
{
	new client = GetClientOfUserId(GetEventInt(event, "userid"));

	// 模型还原
	if (bSuperTanksEnabled)
	{
		if (IsValidPlayer(client) && GetClientTeam(client) == 3)
		{
			SetEntityGravity(client, 1.0);
			SetEntProp(client, Prop_Send, "m_iGlowType", 0);
			SetEntProp(client, Prop_Send, "m_glowColorOverride", 0);
			SetEntProp(client, Prop_Send, "m_bFlashing", 0);
			if (IsTank(client))
			{
				bIsDoubleTankSpawn[client] = false;
                if(tanktype[client] == TANK_Heal)
                {
                    for (new i=1; i<=MaxClients; i++)
                    {			
                        if (IsSpecialInfected(i))
                        {// 特感
                            // 颜色效果去除
                            SetEntProp(i, Prop_Send, "m_glowColorOverride", 0);
                            SetEntProp(i, Prop_Send, "m_iGlowType", 0);
                            SetEntProp(i, Prop_Send, "m_bFlashing", 0);
                        }
                    }
                }
				ExecTankDeath(client);
			}	
			else if (GetClientTeam(client) == 2)
			{
				new entity = -1;
				while ((entity = FindEntityByClassname(entity, "survivor_death_model")) != INVALID_ENT_REFERENCE)
				{
					new Float:Origin[3], Float:EOrigin[3];
					GetClientAbsOrigin(client, Origin);
					GetEntPropVector(entity, Prop_Send, "m_vecOrigin", EOrigin);
					if (Origin[0] == EOrigin[0] && Origin[1] == EOrigin[1] && Origin[2] == EOrigin[2])
					{
						SetEntProp(entity, Prop_Send, "m_hOwnerEntity", client);
					}
				}
			}
		}
	}
	// 死亡爆炸
	if(GetConVarInt(hSuperTanksEnabled) && IsTank(client))
	{
		/* 死亡时产生爆炸和火焰 */
		decl Float:Pos[3];
		GetClientAbsOrigin(client, Pos);
		EmitSoundToAll(SOUND_EXPLODE, client);
		ShowParticle(Pos, PARTICLE_DEATH, 5.0);
		LittleFlower(Pos, EXPLODE);
		CPrintToChatAll("{olive}%N {lightgreen}坦克已经死亡!", client);
		//重力恢复
		SetEntityGravity(client, 1.0);		
		iMoveWarpAbleFlag[client] = 0;
		iMoveCobaltAbleFlag[client] = 0;
		iMoveGhostAbleFlag[client] = 0;
	}
}
//坦克选择提示计时器
public Action:Timer_Tank_Select_Msg(Handle:timer)
{
	Msg_Timer = timer;
	//PrintToChatAll("计时器运行中");
	for (new i = 1; i <= MaxClients; i++)
	{
		if (i > 32) { return Plugin_Continue; }
		if (IsClientInGame(i) && !IsFakeClient(i) && GetClientTeam(i) == 3)
		{
			if (tanktype[i] < 1)
			{
				//CPrintToChat(i, "{lightgreen}输入 !tk 选择你成为坦克时的坦克类型,不选择将系统随机选择.");
				//PrintHintText(i, "输入 !tk 选择你成为坦克时的坦克类型,不选择将系统随机选择.");
				SelectTypePanel(i);				
			}
		}
	}
	//LogMessage("tank_slele");
	return Plugin_Continue;
}
public Action:SmSetTank(client, args)
{
	if(IsValidPlayer(client) && GetClientTeam(client) == 3 && tanktype[client] < 1)
	{
		SelectTypePanel(client);		
	}
	else
	{		
		if (tanktype[client] == TANK_Spawn)// 菌种坦克 1
		{			
			CPrintToChat(client, "{lightgreen}你已经选择了菌种坦克类型！");
		}
		else if (tanktype[client] == TANK_Smasher)// 粉碎坦克 2
		{
			CPrintToChat(client, "{lightgreen}你已经选择了粉碎坦克类型！");
		}
		else if (tanktype[client] == TANK_Warp)// 瞬移坦克 3
		{
			CPrintToChat(client, "{lightgreen}你已经选择了瞬移坦克类型！");
		}
		else if (tanktype[client] == TANK_Meteor)// 陨石坦克 4
		{
			CPrintToChat(client, "{lightgreen}你已经选择了陨石坦克类型！");
		}
		else if (tanktype[client] == TANK_Spitter)// 酸液坦克 5
		{
			CPrintToChat(client, "{lightgreen}你已经选择了酸液坦克类型！");
		}
		else if (tanktype[client] == TANK_Heal)// 治愈坦克 6
		{
			CPrintToChat(client, "{lightgreen}你已经选择了治愈坦克类型！");
		}
		else if (tanktype[client] == TANK_Fire)// 烈焰坦克 7
		{
			CPrintToChat(client, "{lightgreen}你已经选择了烈焰坦克类型！");
		}
		else if (tanktype[client] == TANK_Ice)// 冰霜坦克 8
		{
			CPrintToChat(client, "{lightgreen}你已经选择了冰霜坦克类型！");
		}
		else if (tanktype[client] == TANK_Jockey)// 猴子坦克 9
		{
			CPrintToChat(client, "{lightgreen}你已经选择了猴子坦克类型！");
		}
		else if (tanktype[client] == TANK_Ghost)// 幽灵坦克 10
		{
			CPrintToChat(client, "{lightgreen}你已经选择了幽灵坦克类型！");
		}
		else if (tanktype[client] == TANK_Shock)// 闪电坦克 11
		{
			CPrintToChat(client, "{lightgreen}你已经选择了闪电坦克类型！");
		}
		else if (tanktype[client] == TANK_Witch)// 女巫坦克 12
		{
			CPrintToChat(client, "{lightgreen}你已经选择了女巫坦克类型！");
		}
		else if (tanktype[client] == TANK_Shield)// 护盾坦克 13
		{
			CPrintToChat(client, "{lightgreen}你已经选择了护盾坦克类型！");
		}
		else if (tanktype[client] == TANK_Cobalt)// 神行坦克 14
		{
			CPrintToChat(client, "{lightgreen}你已经选择了神行坦克类型！");
		}
		else if (tanktype[client] == TANK_Jumper)// 跳跃坦克 15
		{
			CPrintToChat(client, "{lightgreen}你已经选择了跳跃坦克类型！");
		}
		else if (tanktype[client] == TANK_Gravity)// 磁力坦克 16
		{
			CPrintToChat(client, "{lightgreen}你已经选择了磁力坦克类型！");
		}
		else if (tanktype[client] == TANK_Boomer)// 胆汁坦克 17
		{
			CPrintToChat(client, "{lightgreen}你已经选择了胆汁坦克类型！");
		}
		else if (tanktype[client] == TANK_RongYan)// 熔岩坦克 18
		{
			CPrintToChat(client, "{lightgreen}你已经选择了熔岩坦克类型！");
		}
		else if (tanktype[client] == TANK_ZhongLi)// 重力坦克 19
		{
			CPrintToChat(client, "{lightgreen}你已经选择了重力坦克类型！");
		}
		else if (tanktype[client] == TANK_KongJu)// 恐惧坦克 20
		{
			CPrintToChat(client, "{lightgreen}你已经选择了恐惧坦克类型！");
		}
		else if (tanktype[client] == TANK_DiZhen)// 地震坦克 21
		{
			CPrintToChat(client, "{lightgreen}你已经选择了地震坦克类型！");
		}
		else if (tanktype[client] == TANK_YouJi)// 游击坦克 22
		{
			CPrintToChat(client, "{lightgreen}你已经选择了游击坦克类型！");
		}
		else if (tanktype[client] == TANK_Double)// 游击坦克 23
		{
			CPrintToChat(client, "{lightgreen}你已经选择了分身坦克类型！");
		}
		else if (tanktype[client] == TANK_Adrenal)// 疯狂暴走坦克 24
		{
			CPrintToChat(client, "{lightgreen}你已经选择了疯狂暴走坦克类型！");
		}
		else if (tanktype[client] == TANK_RenZhe)// 忍者坦克 25
		{
			CPrintToChat(client, "{lightgreen}你已经选择了忍者坦克类型！");
		}
	}
}
/******************************************************
*	tank循环检测控制权事件
*******************************************************/
public Action:CheckFrustration(Handle:timer, any:client)
{
	if (!IsClientConnected(client) || !IsClientInGame(client) || IsFakeClient(client) || (GetClientTeam(client)!=3) || !IsPlayerTank(client) || !IsPlayerAlive(client)) return;
	new frustration = GetEntProp(client, Prop_Send, "m_frustration");
	if (frustration >= 95)
	{
		// 杀死，2次CD
		clientlosscount[client]++;
		if (clientlosscount[client] >= 2)
		{// 处死
			clientlosscount[client] = 0;
			SetEntProp(client, Prop_Send, "m_frustration", 0);// 重置CD时间
			ForcePlayerSuicide(client);// 处死
			PrintHintTextToAll("因丢失2次Tank控制权，玩家【 %N 】已被处死", client);
			//ChangeClientTeam(client, 1); // 旁观/
			///FakeClientCommand(client, "jointeam 3");
			//CreateTimer(0.1, RestoreInfectedTeam, client);  // 再次进入感染者
		}
		else
		{
			PrintHintTextToAll("玩家【 %N 】丢失Tank控制一次，下次丢失将被直接处死", client);
			SetEntProp(client, Prop_Send, "m_frustration", 0);   // 第二次控制CD重置
			CreateTimer(0.1, CheckFrustration, client);
		}
	}
	else
	{// 循环执行此事件
		CreateTimer(0.1+(95-frustration)*0.1, CheckFrustration, client);
	}
}
// 为系统AItank指定随机接受者并设置属性与控制CD等
public Action:SpawnAITank(Handle:timer)
{
	new client = GetRandomPlayer(3);
	if(IsValidPlayer(client, false,true))
	{
		TankSpawner(client);	// 指定为某个玩家
	}
	else
	{
		PrintToChatAll("[丫蛋]没有发现合适的玩家成为坦克,请稍后再试!");
		return;
	}
	
	if(client > 0 && client < MaxClients && IsClientInGame(client) && IsValidEntity(client) && !IsFakeClient(client))
	{
		if(!bIsDoubleTankSpawn[client])
		{
			{
				if (tanktype[client] >= 1)	// 玩家选择tank技能
				{
					SetTankType(client, tanktype[client]);
				}
				else
				{
					new randomtank = GetRandomInt(1, TANK_COUNT); // 给予随机技能
					SetTankType(client, randomtank);
				}
			}
		}		
		else
		{
			SetDoubleTankValue(client);
		}

		for(new j = 1; j <= MaxClients; j++)
		{
			if(IsClientInGame(j) && !IsFakeClient(j))
			{
				EmitSoundToClient(j, SOUND_SPAWN);  // 声音效果
			}
		}
		// 检测tank丢控制事件，创建后10秒运行执行
		if (client > 0 && client < MaxClients && IsClientInGame(client) && IsValidEntity(client) && !IsFakeClient(client))
		{
			CreateTimer(10.0, CheckFrustration, client);
		}
	}
}
public Action:RestoreInfectedTeam(Handle:timer, any:client)
{
	if (!IsClientConnected(client) || !IsClientInGame(client) || IsFakeClient(client) || (GetClientTeam(client)==3)) return;
	FakeClientCommand(client, "jointeam 3");
}

static bool:reswapInfected[MAXPLAYERS+1];
static bool:reghostInfected[MAXPLAYERS+1];
static bool:respawnInfected[MAXPLAYERS+1];
static infectedClass[MAXPLAYERS+1];
static infectedHealth[MAXPLAYERS+1];
static Float:vectors[MAXPLAYERS+1][3];
static Float:infangles[MAXPLAYERS+1][3];
static Float:velocity[MAXPLAYERS+1][3];
static const Float:nullorigin[3];

// 指定某个玩家为tank接受者
static TankSpawner(client)
{	
	for (new i=1; i<=MaxClients; i++) //now to 'disable' all but the guy who is to be tank
	{
		if (i == client) continue; //dont disable the chosen one
		if (!IsClientInGame(i)) continue; //not ingame? skip
		if (GetClientTeam(i) != 3) continue; //not infected? skip
		if (IsFakeClient(i)) continue; //a bot? skip

		if (IsPlayerAlive(i))
		{
			respawnInfected[i] = true;
			if (IsPlayerGhost(i)) reghostInfected[i] = true;
			infectedClass[i] = GetEntProp(i, Prop_Send, "m_zombieClass");
			infectedHealth[i] = GetClientHealth(i);
			GetClientAbsOrigin(i, vectors[i]);
			GetClientEyeAngles(i, infangles[i]);
			GetEntPropVector(i, Prop_Data, "m_vecVelocity", velocity[i])
			
			//TeleportEntity(i, nullorigin, NULL_VECTOR, NULL_VECTOR);
			//ForcePlayerSuicide(i);
		}		
		//ChangeClientTeam(i, 1);
		reswapInfected[i] = true;
	}
	CreateTimer(0.1, RevertPlayerStatus);
}

public Action:RevertPlayerStatus(Handle:timer)
{
	// We restore the player's status
	for (new i=1; i<=MaxClients; i++)
	{
		if (reswapInfected[i])
		{
			//ChangeClientTeam(i, 3);
			reswapInfected[i] = false;
		}
		
		if (respawnInfected[i] && IsValidEntity(i))
		{
			//SpawnInfectedBoss(i, infectedClass[i], reghostInfected[i], false, ItsFinaleTime(), vectors[i], infangles[i], velocity[i]);
			SetEntityHealth(i, infectedHealth[i]);
			respawnInfected[i] = false;
		}
	}
}

stock bool:ItsFinaleTime()
{
	new ent = FindEntityByClassname(-1, "terror_player_manager");

	if (ent > -1)
	{
		new offset = FindSendPropInfo("CTerrorPlayerResource", "m_isFinale");
		if (offset > 0)
		{
			if (GetEntData(ent, offset))
			{
				if (GetEntData(ent, offset) == 1) return true;
			}
		}
	}
	return false;
}

/******************************************************
*	玩家队伍转换
*******************************************************/
public Action:Event_Player_Team(Handle:event, const String:name[], bool:dontBroadcast)
{
	new userid = GetClientOfUserId(GetEventInt(event,"userid"));
	if (userid <= 0 || userid > MaxClients || !IsClientInGame(userid)) { return; }
	new team = GetClientTeam(userid);
	if (IsTank(userid) && team == 3)
	{
		TankChange(userid);
	}
}

/******************************************************
*	被攻击时产生的技能
*******************************************************/
public Action:OnPlayerTakeDamage(victim, &attacker, &inflictor, &Float:damage, &damagetype)
//public Action:OnPlayerTakeDamage(victim, attacker, inflictor, Float:damage, damagetype)
{	
	//CPrintToChatAll("on player take damage");
	//LogMessage("good__");
	if(IsValidPlayer(victim, false))
	{
		CPrintToChatAll("____攻击者：%N, 受伤害者：%N， 攻击伤害值：%d，攻击类型：%d", attacker, victim, damage, damagetype);
	}
	//LogMessage("____攻击者：%N, 受伤害者：%N， 攻击伤害值：%d，攻击类型：%d", attacker, victim, damage, damagetype);
	//damage = 0.0;
	return Plugin_Changed;
}

//timer
//#######################
public Action:ResetPressDelay(Handle:timer, any:client)
{
	//reset press delay
	bJumperPressDelayp[client] = false;
}
public Action:ResetRenZhePressDelay(Handle:timer, any:client)
{
	//reset press delay
	bRenZhePressDelayp[client] = false;
}

public Action:Event_Player_Hurt(Handle:event, const String:name[], bool:dontBroadcast)
{
	new attacker = GetClientOfUserId(GetEventInt(event, "attacker"));   // 攻击者
	new victim = GetClientOfUserId(GetEventInt(event, "userid"));   // 受害人
	
	new damage = GetEventInt(event,"dmg_health");
	new long:damagetype = GetEventInt(event,"type");
	new health_value = GetEventInt(event,"health");

	decl String:weapon[64];
	GetEventString(event, "weapon", weapon, sizeof(weapon));
	if (bSuperTanksEnabled)
	{
		if (damage > 0.0 && IsValidPlayer(victim))
		{
			if (GetClientTeam(victim) == 2)
			{// 幸存伤害
				//if (IsTank(attacker) && damagetype != 2)
				if (IsTank(attacker) && !bIsDoubleTankSpawn[attacker])
				{// TANK攻击
					//CPrintToChatAll("攻击者：%N, 受伤害者：%N， 攻击伤害值：%d，攻击类型：%d， 武器：%s", attacker, victim, damage, damagetype, weapon);
					switch(tanktype[attacker])
					{
						// 菌种
						case TANK_Spawn:
						{
							if (StrEqual(weapon, "tank_claw"))
							{
								//SDKCallVomitOnPlayer(victim, attacker); 胆汁胆汁效果
							}
						}
						// 粉碎
						case TANK_Smasher:
						{
							if (StrEqual(weapon, "tank_claw"))
							{
								//if (random == 1)
								{
									SkillSmashClawKill(victim, attacker);// 必杀
								}
								//else
								{
									//SkillSmashClaw(victim);// 残血
								}
							}
						}
						// 瞬移
						case TANK_Warp:
						{
							if (StrEqual(weapon, "tank_claw"))
							{
								new dmg = RoundFloat(damage / 2);
								DealDamagePlayer(victim, attacker, 2, dmg);
							}
						}
						// 酸液
						case TANK_Spitter:
						{
							if (StrEqual(weapon, "tank_claw"))
							{
								iShowSpitterIndex[attacker]++;
								if(iShowSpitterIndex[attacker] > iShowSpitterTimes)
								{
									iShowSpitterIndex[attacker] = 0;
									new Float:Pos[3];
									GetEntPropVector(victim, Prop_Send, "m_vecOrigin", Pos);
									CreateFakeSpitter(Pos);
								}
							}
						}
						// 烈焰
						case TANK_Fire:
						{
							if (StrEqual(weapon, "tank_claw") || StrEqual(weapon, "tank_rock"))
							{
								SkillFlameClaw(victim);
							}
						}
						// 冰霜
						case TANK_Ice:
						{
							new flags = GetEntityFlags(victim);
							if (flags & FL_ONGROUND)
							{
								SkillIceClaw(victim);
							}
						}
						// 闪电
						case TANK_Shock:
						{
							if (StrEqual(weapon, "tank_claw") || StrEqual(weapon, "tank_rock"))
							{
								SkillElecClawEx(victim);// 眩晕
                                g_iShockHurtFlag[victim] = 1;
                                g_iShockHurtTimes[victim] = 1;
							}
						}						
						// 磁力
						case TANK_Gravity:
						{
							if (StrEqual(weapon, "tank_claw"))
							{
								SkillGravityClaw(victim);
							}
						}
						// 胆汁
						case TANK_Boomer:
						{
							if (StrEqual(weapon, "tank_claw"))
							{
								iShowBoomerIndex[attacker]++;
								if(iShowBoomerIndex[attacker] > iShowBoomerTimes)
								{
									iShowBoomerIndex[attacker] = 0;
									SDKCallVomitOnPlayer(victim, attacker);
								}								
							}
							if (StrEqual(weapon, "tank_rock"))
							{
								SDKCallVomitOnPlayer(victim, attacker);
							}
						}
						// 熔岩
						case TANK_RongYan:
						{
							if (StrEqual(weapon, "tank_claw"))
							{/* 红血攻击 */
								SkillBurnClaw(victim, 1);
							}
							if(StrEqual(weapon, "tank_rock"))
							{/* 火焰石头 */
								SkillCometStrike(victim, MOLOTOV);
							}
						}
						// 地震
						case TANK_DiZhen:
						{
							if (StrEqual(weapon, "tank_claw"))
							{/* 地震技能(被攻击者已经倒地) */
								SkillEarthQuake(victim, attacker);
							}
							if(StrEqual(weapon, "tank_rock"))
							{/* 爆炸石头 */
								SkillCometStrike(victim, EXPLODE);
							}
						}
						// 重力 
						case TANK_ZhongLi:
						{
							if (StrEqual(weapon, "tank_claw"))
							{ /* 重力攻击 */
								SkillGravityClawZL(victim);
							}
						}
						// 恐惧
						case TANK_KongJu:
						{
							if (StrEqual(weapon, "tank_claw") || StrEqual(weapon, "tank_rock"))
							{ /* 致盲攻击 */
								SkillDreadClaw(victim);
							}
						}
					}
				}
			}
			else if(IsTank(victim) && !bIsDoubleTankSpawn[victim])
			{// tank受到攻击
				if (IsSurvivor(attacker))
				{// 攻击者为幸存者
					//CPrintToChatAll("TAN__攻击者：%N, 受伤害者：%N， 攻击伤害值：%d，攻击类型：%d， 武器：%s", attacker, victim, damage, damagetype, weapon);
					switch(tanktype[victim])
					{						 
						// 烈焰
						case TANK_Fire:
						{
							if (StrEqual(weapon, "melee"))
							{
								SkillFlameGush(victim);
							}
						}
						// 陨石
						case TANK_Meteor:
						{
							if (StrEqual(weapon, "melee"))
							{
								if (TankAbility[victim] == 0)
								{
									StartMeteorFall(victim);
								}
							}
						}
						// 酸液
						case TANK_Spitter:
						{
							if (StrEqual(weapon, "melee"))
							{
								new x = CreateFakeClient("Spitter");
								if (x > 0)
								{
									new Float:Pos[3];
									GetClientAbsOrigin(victim, Pos);
									TeleportEntity(x, Pos, NULL_VECTOR, NULL_VECTOR);	
									SDKCallSpitBurst(x);
									KickClient(x);
								}
							}
						}
						// 幽灵
						case TANK_Ghost:
						{
							if (bGhostDisarm)
							{
								if(StrEqual(weapon, "melee"))
								{
									//ForceWeaponDrop(attacker); 武器掉落
									//EmitSoundToClient(attacker, "npc/infected/action/die/male/death_42.wav", victim);
								}
							}
						}
						// 护盾
						case TANK_Shield:
						{
							//PrintToChatAll("伤害类型: %u", damagetype);
							if (damagetype == 134217792)
							{// 煤气爆炸等伤害，护盾解除
								DeactivateShield(victim);
								//CPrintToChatAll("{green}玩家%N的护盾效果消失，将承受伤害");
							}
							else
							{
								if(!bShieldDemageFlag[victim])
								{// 护盾保护中
									//CPrintToChatAll("护盾保护: %d, __%d", damage, health_value);
									if(damagetype != 268435464 && damagetype != 8 && damagetype != 2056 )
									{
                                        //CPrintToChatAll("sound");
										EmitSoundToClient(attacker, SOUND_STEEL);
										EmitSoundToClient(victim, SOUND_STEEL);
									}
									//SetEntityHealth(tankid[victim], (damage + GetEventInt(event,"health"))); 
									SetEntProp(victim, Prop_Data, "m_iHealth", damage + health_value);
								}
								else
								{// 无护盾，受到伤害
									//CPrintToChatAll("护盾无保护");
								}
							}
						}
						// 熔岩
						case TANK_RongYan:
						{
							if (StrEqual(weapon, "melee") || StrEqual(weapon, "chainsaw"))
							{/* 火焰喷发 */
								SkillFlameGushRY(attacker, victim);
							}
						}
						// 重力
						case TANK_ZhongLi:
						{
							if (StrEqual(weapon, "melee") || StrEqual(weapon, "chainsaw"))
							{/* 钢铁皮肤 */
								EmitSoundToClient(attacker, SOUND_STEEL);
								SetEntityHealth(victim, (GetEventInt(event,"dmg_health") + GetEventInt(event,"health")));
							}
						}
					}
				}
			}
		}
	}	
}

/******************************************************
*	其他子程序
*******************************************************/
bool:IsPlayerIncapped(client)
{
	if (GetEntProp(client, Prop_Send, "m_isIncapacitated", 1))
		return true;
	else
		return false;
}

/*
GetAnyClient()
{
	for(new i = 1; i <= MaxClients; i++)
	{
		if(IsValidEntity(i) && IsClientInGame(i))
			return i;
	}
	return -1;
}
*/

/* 获取随机有效幸存者，给予tank */
public GetRandomPlayer(Team)
{
	new Handle:array;
	array = CreateArray(1, 0);
	
	for(new i = 1; i <= MaxClients; i++)
	{
		if(!IsValidPlayer(i, false) || GetClientTeam(i) != Team)
			continue;
			
		PushArrayCell(array, i);
	}
	
	
	if (GetArraySize(array) <= 0)
		return 0;
	
	new maxsize = GetArraySize(array) - 1;
	new clientNum = GetArrayCell(array, GetRandomInt(0, maxsize));
//PrintToChatAll("当前轮换tank获得者【 %N 】", clientNum);
//PrintToChatAll("当前最大玩家数 %d ", maxsize);
	new tank_count_temp = 0;
	while(IsPlayerTank(clientNum) || GetClientTeam(clientNum) != 3 || IsFakeClient(clientNum) || !IsClientInGame(clientNum))
	{
	 //   PrintToChatAll("当tank_count %d ", tank_count_temp);
		if(tank_count_temp >= maxsize)
		{
			for(new i = 1; i <= MaxClients; i++)
			{
				if(!IsPlayerTank(i) && IsValidPlayer(i, false) && IsValidEntity(i) && GetClientTeam(i) == 3)
				{
					//PrintToChatAll("顺序给予");
					return i;
				}
			}
			//PrintToChatAll("没有可用玩家");
			return -1;
		}
		tank_count_temp++;
		clientNum = GetArrayCell(array, GetRandomInt(0, maxsize));
		//PrintToChatAll("重复tank获得者__【 %N 】", clientNum);
	}
	return clientNum;
}

//坦克属性修正,第一次重生属性设置无效后在重新设置
public Action:tankspeedcheck(Handle:timer, any:client)
{
	if (!IsTank(client) || tanktype[client] == TANK_Cobalt) { return Plugin_Stop; }
	new Float:getspeed = GetEntDataFloat(client, g_iLaggedMovementO);
	new gethealth = GetEntProp(client, Prop_Data, "m_iMaxHealth");
	new maxhealth;
	new tank_type = tanktype[client];
	if (getspeed != flTankSpeed[tank_type] || gethealth != iTankExtraHealth[tank_type])
	{
		maxhealth = iTankExtraHealth[tank_type];
		SetEntProp(client, Prop_Data, "m_iMaxHealth", maxhealth);
		SetEntProp(client, Prop_Data, "m_iHealth", maxhealth);
		SetEntDataFloat(client,g_iLaggedMovementO, flTankSpeed[tank_type] ,true);
		return Plugin_Stop;
	}
	if (changehealth >= 1)
	{
		SetEntProp(client, Prop_Data, "m_iHealth", changehealth);
		changehealth = 0;
	}
	return Plugin_Continue;
}

/*  坦克转换控制 */
public TankChange(client)
{
	if(client <= 0 || client > MaxClients)
		return;
	if(!IsClientInGame(client))
		return;

	if (!IsFakeClient(client))
	{
		changehealth = GetEntProp(client, Prop_Data, "m_iHealth");
	}
	//恢复数据
	SetEntityGravity(client, 1.0);
	SetEntityRenderMode(client, RENDER_TRANSCOLOR);
	SetEntityRenderColor(client, 255, 255, 255, 255);


	//杀死坦克
	//ForcePlayerSuicide(client);

	//重生坦克
	//new flager = GetAnyClient();
	//new flag = GetCommandFlags("z_spawn tank auto");
	//SetCommandFlags("z_spawn tank auto", flag & ~FCVAR_CHEAT);
	//FakeClientCommand(flager, "z_spawn tank auto");
}


public SelectTypePanel(client)
{
	new Handle:menu = CreateMenu(SelectTankMenu);
	if(bTankEnabled[1])
	{
		AddMenuItem(menu, "spawn", "菌种坦克");
	}	
	if(bTankEnabled[2])
	{
		AddMenuItem(menu, "smasher", "粉碎坦克");
	}	
	if(bTankEnabled[3])
	{
		AddMenuItem(menu, "warp", "心灵坦克");
	}	
	if(bTankEnabled[4])
	{
		AddMenuItem(menu, "meteor", "陨石坦克");
	}	
	if(bTankEnabled[5])
	{
		AddMenuItem(menu, "spitter", "酸液坦克");
	}	
	if(bTankEnabled[6])
	{
		AddMenuItem(menu, "heal", "治愈坦克");
	}	
	if(bTankEnabled[7])
	{
		AddMenuItem(menu, "fire", "烈焰坦克");
	}
	if(bTankEnabled[8])
	{
		AddMenuItem(menu, "ice", "冰霜坦克");
	}	
	if(bTankEnabled[9])
	{
		AddMenuItem(menu, "jockey", "猴子坦克");
	}
	if(bTankEnabled[10])
	{
		AddMenuItem(menu, "ghost", "幽灵坦克");
	}	
	if(bTankEnabled[11])
	{
		AddMenuItem(menu, "shock", "闪电坦克");
	}	
	if(bTankEnabled[12])
	{
		AddMenuItem(menu, "witch", "女巫坦克");
	}	
	if(bTankEnabled[13])
	{
		AddMenuItem(menu, "shield", "护盾坦克");
	}	
	if(bTankEnabled[14])
	{
		AddMenuItem(menu, "cobalt", "神行坦克");
	}	
	if(bTankEnabled[15])
	{
		AddMenuItem(menu, "jumper", "跳跃坦克");
	}	
	if(bTankEnabled[16])
	{
		AddMenuItem(menu, "gravity", "磁力坦克");
	}
	if(bTankEnabled[17])
	{
		AddMenuItem(menu, "boomer", "胆汁坦克");
	}  
	if(bTankEnabled[18])
	{
		AddMenuItem(menu, "rongyan", "熔岩坦克");
	} 
	if(bTankEnabled[19])
	{
		AddMenuItem(menu, "zhongli", "重力坦克");
	} 
	if(bTankEnabled[20])
	{
		AddMenuItem(menu, "kongju", "恐惧坦克");
	} 
	if(bTankEnabled[21])
	{
		AddMenuItem(menu, "dizhen", "地震坦克");
	} 	
	if(bTankEnabled[22])
	{
		AddMenuItem(menu, "youji", "游击坦克");
	} 
	if(bTankEnabled[23])
	{
		AddMenuItem(menu, "double", "分身坦克");
	}
	if(bTankEnabled[24])
	{
		AddMenuItem(menu, "adrenal", "暴走坦克");
	}
	if(bTankEnabled[25])
	{
		AddMenuItem(menu, "renzhe", "忍者坦克");
	}
	

	SetMenuTitle(menu, "请选择您的坦克类型:");
	DisplayMenu(menu, client, MENU_TIME_FOREVER);
}

public SelectTankMenu(Handle:menu, MenuAction:action, client, param)
{
	if (!IsValidPlayer(client)) { return; }
	
	switch(action)
	{
	case MenuAction_End:
		{
			CloseHandle(menu);
		}
	case MenuAction_Select:
		{
			new String:item1[64];
			GetMenuItem(menu, param, item1, sizeof(item1));
			if (StrEqual(item1, "spawn", false))
			{
				CPrintToChat(client, "{olive}已经保存你选择的{lightgreen}菌种坦克");
				tanktype[client] = TANK_Spawn;
				ClientCommand(client, "sm_s");
			}
			else if (StrEqual(item1, "smasher", false))
			{
				CPrintToChat(client, "{olive}已经保存你选择的{lightgreen}粉碎坦克");
				tanktype[client] = TANK_Smasher;
				ClientCommand(client, "sm_s");
			}
			else if (StrEqual(item1, "warp", false))
			{
				CPrintToChat(client, "{olive}已经保存你选择的{lightgreen}心灵坦克");
				tanktype[client] = TANK_Warp;
				ClientCommand(client, "sm_s");
			}
			else if (StrEqual(item1, "meteor", false))
			{
				CPrintToChat(client, "{olive}已经保存你选择的{lightgreen}陨石坦克");
				tanktype[client] = TANK_Meteor;
				ClientCommand(client, "sm_s");
			}
			else if (StrEqual(item1, "spitter", false))
			{
				CPrintToChat(client, "{olive}已经保存你选择的{lightgreen}酸液坦克");
				tanktype[client] = TANK_Spitter;
				ClientCommand(client, "sm_s");
			}
			else if (StrEqual(item1, "heal", false))
			{
				CPrintToChat(client, "{olive}已经保存你选择的{lightgreen}治愈坦克");
				tanktype[client] = TANK_Heal;
				ClientCommand(client, "sm_s");
			}
			else if (StrEqual(item1, "fire", false))
			{
				CPrintToChat(client, "{olive}已经保存你选择的{lightgreen}烈焰坦克");
				tanktype[client] = TANK_Fire;
				ClientCommand(client, "sm_s");
			}
			else if (StrEqual(item1, "ice", false))
			{
				CPrintToChat(client, "{olive}已经保存你选择的{lightgreen}冰霜坦克");
				tanktype[client] = TANK_Ice;
				ClientCommand(client, "sm_s");
			}
			else if (StrEqual(item1, "jockey", false))
			{
				CPrintToChat(client, "{olive}已经保存你选择的{lightgreen}猴子坦克");
				tanktype[client] = TANK_Jockey;
				ClientCommand(client, "sm_s");
			}
			else if (StrEqual(item1, "ghost", false))
			{
				CPrintToChat(client, "{olive}已经保存你选择的{lightgreen}幽灵坦克");
				tanktype[client] = TANK_Ghost;
				ClientCommand(client, "sm_s");
			}
			else if (StrEqual(item1, "shock", false))
			{
				CPrintToChat(client, "{olive}已经保存你选择的{lightgreen}闪电坦克");
				tanktype[client] = TANK_Shock;
				ClientCommand(client, "sm_s");
			}
			else if (StrEqual(item1, "witch", false))
			{
				CPrintToChat(client, "{olive}已经保存你选择的{lightgreen}女巫坦克");
				tanktype[client] = TANK_Witch;
				ClientCommand(client, "sm_s");
			}
			else if (StrEqual(item1, "shield", false))
			{
				CPrintToChat(client, "{olive}已经保存你选择的{lightgreen}护盾坦克");
				tanktype[client] = TANK_Shield;
				ClientCommand(client, "sm_s");
			}
			else if (StrEqual(item1, "cobalt", false))
			{
				CPrintToChat(client, "{olive}已经保存你选择的{lightgreen}神行坦克");
				tanktype[client] = TANK_Cobalt;
				ClientCommand(client, "sm_s");
			}
			else if (StrEqual(item1, "jumper", false))
			{
				CPrintToChat(client, "{olive}已经保存你选择的{lightgreen}跳跃坦克");
				tanktype[client] = TANK_Jumper;
				ClientCommand(client, "sm_s");
			}
			else if (StrEqual(item1, "gravity", false))
			{
				CPrintToChat(client, "{olive}已经保存你选择的{lightgreen}磁力坦克");
				tanktype[client] = TANK_Gravity;
				ClientCommand(client, "sm_s");
			}
			else if (StrEqual(item1, "boomer", false))
			{
				CPrintToChat(client, "{olive}已经保存你选择的{lightgreen}胆汁坦克");
				tanktype[client] = TANK_Boomer;
				ClientCommand(client, "sm_s");
			}
			else if (StrEqual(item1, "rongyan", false))
			{
				CPrintToChat(client, "{olive}已经保存你选择的{lightgreen}熔岩坦克");
				tanktype[client] = TANK_RongYan;
				ClientCommand(client, "sm_s");
			}
			else if (StrEqual(item1, "zhongli", false))
			{
				CPrintToChat(client, "{olive}已经保存你选择的{lightgreen}重力坦克");
				tanktype[client] = TANK_ZhongLi;
				ClientCommand(client, "sm_s");
			}
			else if (StrEqual(item1, "kongju", false))
			{
				CPrintToChat(client, "{olive}已经保存你选择的{lightgreen}恐惧坦克");
				tanktype[client] = TANK_KongJu;
				ClientCommand(client, "sm_s");
			}
			else if (StrEqual(item1, "dizhen", false))
			{
				CPrintToChat(client, "{olive}已经保存你选择的{lightgreen}地震坦克");
				tanktype[client] = TANK_DiZhen;
				ClientCommand(client, "sm_s");
			}
			else if (StrEqual(item1, "youji", false))
			{
				CPrintToChat(client, "{olive}已经保存你选择的{lightgreen}游击坦克");
				tanktype[client] = TANK_YouJi;
				ClientCommand(client, "sm_s");
			}
			else if (StrEqual(item1, "double", false))
			{
				CPrintToChat(client, "{olive}已经保存你选择的{lightgreen}分身坦克");
				tanktype[client] = TANK_Double;
				ClientCommand(client, "sm_s");
			}
			else if (StrEqual(item1, "adrenal", false))
			{
				CPrintToChat(client, "{olive}已经保存你选择的{lightgreen}暴走坦克");
				tanktype[client] = TANK_Adrenal;
				ClientCommand(client, "sm_s");
			}
			else if (StrEqual(item1, "renzhe", false))
			{
				CPrintToChat(client, "{olive}已经保存你选择的{lightgreen}忍者坦克");
				tanktype[client] = TANK_RenZhe;
				ClientCommand(client, "sm_s");
			}
			else
			{
				CPrintToChat(client, "{olive}已经保存你选择的{lightgreen}菌种坦克");
				tanktype[client] = TANK_Spawn;
				ClientCommand(client, "sm_s");
			}		  
		}
	}	
}
//
public bool:IsPlayerTank (client)
{
	if(IsValidPlayer(client))
	{
	
		new String:class[150];
		GetClientModel(client, class, sizeof(class));
		return (StrContains(class, "hulk", false) != -1);
	}
	else
	{
		return false;
	}
//	return ((GetClientTeam(client) == 3) && (GetEntProp(client, Prop_Send, "m_zombieClass") == ZC_TANK));
}
//////////////////////////////////////////
//** 常用函数 **************************//
//////////////////////////////////////////
/* 判断玩家是否有效 */
stock bool:IsValidPlayer(Client, bool:AllowBot = true, bool:AllowDeath = true)
{
	if (Client < 1 || Client > MaxClients)
		return false;
	if (!IsClientConnected(Client) || !IsClientInGame(Client))
		return false;
	if (!AllowBot)
	{
		if (IsFakeClient(Client))
			return false;
	}

	if (!AllowDeath)
	{
		if (!IsPlayerAlive(Client))
			return false;
	}	
	
	return true;
}
stock bool:IsTank(client, bool:AllowBot = true, bool:AllowDeath = true)
{
	if (IsValidPlayer(client, AllowBot, AllowDeath))
	{
		new String:class[150];
		GetClientModel(client, class, sizeof(class));
		return (StrContains(class, "hulk", false) != -1);
	}
	return false;
}
bool:IsWitch(client)
{
	if (IsValidPlayer(client))
	{
		decl String: classname[32];
		GetEdictClassname(client, classname, sizeof(classname));
		if (StrEqual(classname, "witch"))
			return true;
		return false;
	}
	return false;
}
stock CountTanks()
{
	iNumTanks = 0;
	for (new i=1; i<=MaxClients; i++)
	{
		if (IsTank(i))
		{
			iNumTanks++;
		}
	}
}
public Action:TankLifeCheck(Handle:timer, any:client)
{
	if (IsClientInGame(client) && IsFakeClient(client) && GetClientTeam(client) == 3)
	{
		new lifestate = GetEntData(client, FindSendPropInfo("CTerrorPlayer", "m_lifeState"));
		if (lifestate == 0)
		{
			new bot = CreateFakeClient("Tank");
			if (bot > 0)
			{
				new Float: Origin[3], Float:Angles[3];
				GetClientAbsOrigin(client, Origin);
				GetClientAbsAngles(client, Angles);
				KickClient(client);
				TeleportEntity(bot, Origin, Angles, NULL_VECTOR);
				SpawnInfected(bot, 8, true);
			}
		}	
	}
}
stock bool:IsSurvivor(client)
{
	if (IsValidPlayer(client) && GetClientTeam(client) == 2)
	{
		return true;
	}
	return false;
}
stock GetEntityRenderColor(entity)
{
	if (entity > 0)
	{
		new offset = GetEntSendPropOffs(entity, "m_clrRender");
		new r = GetEntData(entity, offset, 1);
		new g = GetEntData(entity, offset+1, 1);
		new b = GetEntData(entity, offset+2, 1);
		decl String:rgb[10];
		Format(rgb, sizeof(rgb), "%d%d%d", r, g, b);
		new color = StringToInt(rgb);
		return color;
	}
	return 0;	
}
stock RGB_TO_INT(red, green, blue) 
{
	return (blue * 65536) + (green * 256) + red;
}
stock SpawnInfected(client, Class, bool:bAuto=true)
{
	new bool:resetGhostState[MaxClients+1];
	new bool:resetIsAlive[MaxClients+1];
	new bool:resetLifeState[MaxClients+1];
	ChangeClientTeam(client, 3);
	new String:g_sBossNames[10][10]={"","smoker","boomer","hunter","spitter","jockey","charger","witch","tank","survivor"};
	decl String:options[30];
	if (Class < 1 || Class > 8) return false;
	if (GetClientTeam(client) != 3) return false;
	if (!IsClientInGame(client)) return false;
	if (IsPlayerAlive(client)) return false;
	
	for (new i=1; i<=MaxClients; i++){ 
		if (i == client) continue; //dont disable the chosen one
		if (!IsClientInGame(i)) continue; //not ingame? skip
		if (GetClientTeam(i) != 3) continue; //not infected? skip
		if (IsFakeClient(i)) continue; //a bot? skip
		
		if (IsPlayerGhost(i)){
			resetGhostState[i] = true;
			SetPlayerGhostStatus(i, false);
			resetIsAlive[i] = true; 
			SetPlayerIsAlive(i, true);
		}
		else if (!IsPlayerAlive(i)){
			resetLifeState[i] = true;
			SetPlayerLifeState(i, false);
		}
	}
	Format(options,sizeof(options),"%s%s",g_sBossNames[Class],(bAuto?" auto":""));
	CheatCommand(client, "z_spawn", options);
	if (IsFakeClient(client)) KickClient(client);
	// We restore the player's status
	for (new i=1; i<=MaxClients; i++){
		if (resetGhostState[i]) SetPlayerGhostStatus(i, true);
		if (resetIsAlive[i]) SetPlayerIsAlive(i, false);
		if (resetLifeState[i]) SetPlayerLifeState(i, true);
	}

	return true;
}

stock bool:IsPlayerIncap(client)
{
	if (GetEntProp(client, Prop_Send, "m_isIncapacitated", 1)) return true;
	return false;
}
stock NearestSurvivor(j)
{
		new target, Float:InfectedPos[3], Float:SurvivorPos[3], Float:nearest = 0.0;
   	for (new i=1; i<=MaxClients; i++)
		{
			if (IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(i) == 2 && ChaseTarget[i] == 0)
		{
			GetClientAbsOrigin(j, InfectedPos);
			GetClientAbsOrigin(i, SurvivorPos);
						new Float:distance = GetVectorDistance(InfectedPos, SurvivorPos);
						if (nearest == 0.0)
			{
				nearest = distance;
				target = i;
			}
			else if (nearest > distance)
			{
				nearest = distance;
				target = i;
			}
		} 
		}
		return target;
}
stock CountSurvivorsAliveAll()
{
	new count = 0;
	for (new i=1; i<=MaxClients; i++)
	{
		if (IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(i) == 2)
		{
			count++;
		}
	}
	return count;
}
stock CountInfectedAll()
{
	new count = 0;
	for (new i=1;i<=MaxClients;i++)
	{
		if (IsClientInGame(i) && GetClientTeam(i) == 3)
		{
			count++;
		}
	}
	return count;
}
bool:IsPlayerBurning(i)
{
	new Float:IsBurning = GetEntPropFloat(i, Prop_Send, "m_burnPercent");
	if (IsBurning > 0) 
		return true;
	return false;
}
////////////////////////////////////////////////////
//************************************************//
////////////////////////////////////////////////////
// 移植supertank 
// 出生tank拥有的特殊属性
public Action:Timer_UnFreeze(Handle:timer, any:client)
{
	if (client > 0)
	{
		if (IsClientInGame(client) && IsPlayerAlive(client) && GetClientTeam(client) == 2)
		{
			SetEntityRenderMode(client, RenderMode:3);
			SetEntityRenderColor(client, 255, 255, 255, 255);
			SetEntityMoveType(client, MOVETYPE_WALK);
		}
	}
}
public Action:Timer_ResetGravity(Handle:timer, any:client)
{
	if (client > 0)
	{
		if (IsClientInGame(client))
		{
			SetEntityGravity(client, 1.0);
		}
	}
}
// 菌种
public Action:Timer_AttachSPAWN(Handle:timer, any:client)
{
	if (IsTank(client) && tanktype[client] == TANK_Spawn)
	{
		AttachParticle(client, PARTICLE_SPAWN, 1.2, 0.0);
		return Plugin_Continue;
	}
	return Plugin_Stop;
}
// 菌种
public Action:Timer_AttachSPAWNEx(Handle:timer, any:client)
{
	if (IsTank(client) && tanktype[client] == TANK_Spawn)
	{
		decl Float:g_pos[3];
        GetClientEyePosition(client, g_pos);            
        CreateGasCloud(client, g_pos);// 毒雾伤害
        
		return Plugin_Continue;
	}
	return Plugin_Stop;
}
// 烈焰
public Action:Timer_AttachFIRE(Handle:timer, any:client)
{
	if (IsTank(client) && tanktype[client] == TANK_Fire)
	{
		AttachParticle(client, PARTICLE_FIRE, 0.8, 0.0);
		return Plugin_Continue;
	}
	return Plugin_Stop;
}
public Action:Timer_AttachFIRE_Rock(Handle:timer, any:entity)
{
	if (IsValidEntity(entity))
	{
		decl String: classname[32];
		GetEdictClassname(entity, classname, sizeof(classname));
		if (StrEqual(classname, "tank_rock"))
		{
			IgniteEntity(entity, 100.0);
			return Plugin_Continue;
		}
	}
	return Plugin_Stop;
}
// 冰霜
public Action:Timer_AttachICE(Handle:timer, any:client)
{
	if (IsTank(client) && tanktype[client] == TANK_Ice)
	{
		AttachParticle(client, PARTICLE_ICE, 2.0, 30.0);
		return Plugin_Continue;
	}
	return Plugin_Stop;
}
// 酸液
public Action:Timer_SpitSound(Handle:timer, any:client)
{
	if (IsTank(client) && tanktype[client] == TANK_Spitter)
	{
		EmitSoundToAll("player/spitter/voice/warn/spitter_spit_02.wav", client);
	}
}
public Action:Timer_AttachSPIT(Handle:timer, any:client)
{
	if (IsTank(client) && tanktype[client] == TANK_Spitter)
	{
		AttachParticle(client, PARTICLE_SPIT, 2.0, 30.0);
		return Plugin_Continue;
	}
	return Plugin_Stop;
}
public Action:Timer_AttachSPIT_Rock(Handle:timer, any:entity)
{
	if (IsValidEntity(entity))
	{
		decl String: classname[32];
		GetEdictClassname(entity, classname, sizeof(classname));
		if (StrEqual(classname, "tank_rock"))
		{
			AttachParticle(entity, PARTICLE_SPITPROJ, 0.8, 0.0);
			return Plugin_Continue;
		}
	}
	return Plugin_Stop;
}
// 闪电
public Action:Timer_AttachELEC(Handle:timer, any:client)
{
	if (IsTank(client) && tanktype[client] == TANK_Shock)
	{
		AttachParticle(client, PARTICLE_ELEC, 0.8, 30.0);
		return Plugin_Continue;
	}
	return Plugin_Stop;
}
public Action:Timer_AttachELEC_Rock(Handle:timer, any:entity)
{
	if (IsValidEntity(entity))
	{
		decl String: classname[32];
		GetEdictClassname(entity, classname, sizeof(classname));
		if (StrEqual(classname, "tank_rock"))
		{
			AttachParticle(entity, PARTICLE_ELEC, 0.8, 0.0);
			return Plugin_Continue;
		}
	}
	return Plugin_Stop;
}
// 女巫
public Action:Timer_AttachBLOOD(Handle:timer, any:client)
{
	if (IsTank(client) && tanktype[client] == TANK_Witch)
	{
		AttachParticle(client, PARTICLE_BLOOD, 0.8, 30.0);
		return Plugin_Continue;
	}
	return Plugin_Stop;
}
public Action:Timer_Spawn(Handle:timer, any:client)
{
	if (IsTank(client) && tanktype[client] == TANK_Witch)
	{
		SpawnWitch(client);
		return Plugin_Continue;
	}
	return Plugin_Stop;
}

// 陨石
public Action:Timer_AttachMETEOR(Handle:timer, any:client)
{
	if (IsTank(client) && tanktype[client] == TANK_Meteor)
	{
		AttachParticle(client, PARTICLE_METEOR, 6.0, 30.0);
		return Plugin_Continue;
	}
	return Plugin_Stop;
}
// 护盾
public Action:ActivateShieldTimer(Handle:timer, any:client)
{
	ActivateShield(client);
}
stock ActivateShield(client)
{
	if (IsTank(client) && tanktype[client] == TANK_Shield)
	{
		decl Float:Origin[3];
		GetClientAbsOrigin(client, Origin);
		Origin[2] -= 120.0;
		new entity = CreateEntityByName("prop_dynamic");
		if (IsValidEntity(entity))
		{
			decl String:tName[64];
			Format(tName, sizeof(tName), "Tank%d", client);
			DispatchKeyValue(client, "targetname", tName);
			GetEntPropString(client, Prop_Data, "m_iName", tName, sizeof(tName));
			DispatchKeyValue(entity, "targetname", "Player");
			DispatchKeyValue(entity, "parentname", tName);
			DispatchKeyValue(entity, "model", "models/props_unique/airport/atlas_break_ball.mdl");
			DispatchKeyValueVector(entity, "origin", Origin);
			DispatchSpawn(entity);
			SetVariantString(tName);
			AcceptEntityInput(entity, "SetParent", entity, entity);
			SetEntityRenderMode(entity, RenderMode:3);
	  	 	SetEntityRenderColor(entity, 25, 125, 125, 50);
			SetEntData(entity, GetEntSendPropOffs(entity, "m_CollisionGroup"), 1, 1, true);
			SetEntProp(entity, Prop_Send, "m_hOwnerEntity", client);			
			//SetEntProp(client, Prop_Data, "m_takedamage", 1, 1);			
		}
		bShieldDemageFlag[client] = false;
		CPrintToChatAll("{lightgreen}玩家{green}【%N】{lightgreen}护盾启动，免疫一般伤害!");
	}
}
stock DeactivateShield(client)
{
	if (IsTank(client) && tanktype[client] == TANK_Shield)
	{
		new entity = -1;
		while ((entity = FindEntityByClassname(entity, "prop_dynamic")) != INVALID_ENT_REFERENCE)
		{
			decl String:model[128];
			GetEntPropString(entity, Prop_Data, "m_ModelName", model, sizeof(model));
			if (StrEqual(model, "models/props_unique/airport/atlas_break_ball.mdl"))
			{
				new owner = GetEntProp(entity, Prop_Send, "m_hOwnerEntity");
				if (owner == client)
				{
					AcceptEntityInput(entity, "Kill");
				}
			}
		}
		//SetEntProp(client, Prop_Data, "m_takedamage", 2, 1);
		CreateTimer(flShieldShieldsDownInterval, ActivateShieldTimer, client, TIMER_FLAG_NO_MAPCHANGE);
		bShieldDemageFlag[client] = true;
	}
}
stock CreateFakeSpitter(Float:Pos[3])
{
	new x = CreateFakeClient("Spitter");
	if (x > 0)
	{
		TeleportEntity(x, Pos, NULL_VECTOR, NULL_VECTOR);	
		SDKCallSpitBurst(x);
		KickClient(x);
	}
}
//=============================
// FUNCTIONS
//=============================
// tank石头产生
public OnEntityCreated(entity, const String:classname[])
{
	if (bSuperTanksEnabled)
	{
		if (StrEqual(classname, "tank_rock", true))
		{
			CreateTimer(0.1, RockThrowTimer, _, TIMER_FLAG_NO_MAPCHANGE);
		}
	}
}
// 石头落地损坏效果
public OnEntityDestroyed(entity)
{
	if (!IsServerProcessing()) return;
	if (bSuperTanksEnabled)
	{
		if (entity > 32 && IsValidEntity(entity))
		{
			new String:classname[32];
			GetEdictClassname(entity, classname, sizeof(classname));
			if (StrEqual(classname, "tank_rock", true))
			{
				new color = GetEntityRenderColor(entity);
				switch(color)
				{
					// 烈焰石头
					case 12800:
					{
						new prop = CreateEntityByName("prop_physics");
						if (prop > 32 && IsValidEntity(prop))
						{
							new Float:Pos[3];
							GetEntPropVector(entity, Prop_Send, "m_vecOrigin", Pos);
							Pos[2] += 10.0;
							DispatchKeyValue(prop, "model", "models/props_junk/gascan001a.mdl");
							DispatchSpawn(prop);
							SetEntData(prop, GetEntSendPropOffs(prop, "m_CollisionGroup"), 1, 1, true);
							TeleportEntity(prop, Pos, NULL_VECTOR, NULL_VECTOR);
							AcceptEntityInput(prop, "break");
						}
					}
					// 酸液石头
					case 12115128:
					{
						new Float:Pos[3];
						GetEntPropVector(entity, Prop_Send, "m_vecOrigin", Pos);
						CreateFakeSpitter(Pos);
					}
				}
			}
		}
	}
}
// tank附加属性
//地震技能
public SkillEarthQuake(target, userid)
{
	decl Float:Pos[3], Float:tPos[3];


	if(IsPlayerIncapped(target))
	{
		for(new i = 1; i <= GetMaxClients(); i++)
		{
			if (i > 32) { return; }
			if(!IsClientInGame(i) || GetClientTeam(i) != 2)
				continue;

			GetClientAbsOrigin(userid, Pos);
			GetClientAbsOrigin(i, tPos);
			if(GetVectorDistance(tPos, Pos) < GetConVarFloat(sm_lastboss_quake_radius))
			{
				EmitSoundToClient(i, SOUND_QUAKE);
				ScreenShake(i, 60.0);
				Smash(userid, i, GetConVarFloat(sm_lastboss_quake_force), 1.0, 1.5);
			}
		}
	}
}

//致盲黑屏
public SkillDreadClaw(target)
{
	visibility = GetConVarInt(sm_lastboss_dreadrate);
	CreateTimer(GetConVarFloat(sm_lastboss_dreadinterval), DreadTimer, target);
	EmitSoundToAll(SOUND_DCLAW, target);
	ScreenFade(target, 0, 0, 0, visibility, 0, 0);
}

//重力攻击
public SkillGravityClawZL(target)
{
	SetEntityGravity(target, fZhongLiClawValue);  // 拍中后玩家重力值
	CreateTimer(GetConVarFloat(sm_lastboss_gravityinterval), GravityTimer, target); // 多久后恢复
	EmitSoundToAll(SOUND_GCLAW, target);
	ScreenFade(target, 0, 0, 100, 80, 4000, 1);
	ScreenShake(target, 30.0);
}

//红血攻击(type=1是红血攻击的DMG,type=2是火焰喷发的DMG)
public SkillBurnClaw(target, type)
{
	new health = GetClientHealth(target);
	new Float:buffer = GetEntPropFloat(target, Prop_Send, "m_healthBuffer");
	new String:strbuffer[32];
	new dmg;
	if (type == 1)
	{
		if (health <= 1 && buffer > 1.0)
		{
			FloatToString(buffer, strbuffer, sizeof(strbuffer));
			dmg = StringToInt(strbuffer) - GetConVarInt(sm_lastboss_tankry_hxdmg);
		}
		else
		{
			dmg = health - GetConVarInt(sm_lastboss_tankry_hxdmg);
		}
	}
	else if (type == 2)
	{
		if (health <= 1 && buffer > 1.0)
		{
			FloatToString(buffer, strbuffer, sizeof(strbuffer));
			dmg = StringToInt(strbuffer) - 50;
		}
		else
		{
			dmg = health - 50;
		}
	}
	else
	{
		dmg = health;
	}

	if(health > 0 && !IsPlayerIncapped(target))
	{
		if (dmg < 1)
		{
			if (health <= 1 && buffer > 1.0)
			{
				SetEntPropFloat(target, Prop_Send, "m_healthBuffer", 1.0);
			}
			else
			{
				SetEntityHealth(target, 1);
			}
		}
		else
		{
			if (health <= 1 && buffer > 1.0)
			{
				SetEntPropFloat(target, Prop_Send, "m_healthBuffer", float(dmg));
			}
			else
			{
				SetEntityHealth(target, dmg);
			}
		}
	}
	EmitSoundToAll(SOUND_BCLAW, target);
	ScreenFade(target, 200, 0, 0, 150, 80, 1);
	ScreenShake(target, 50.0);
}

//火焰石头和爆炸石头
public SkillCometStrike(target, type)
{
	decl Float:pos[3];
	GetClientAbsOrigin(target, pos);

	if(type == MOLOTOV)
	{
		LittleFlower(pos, EXPLODE);
		LittleFlower(pos, MOLOTOV);
	}
	else if(type == EXPLODE)
	{
		LittleFlower(pos, EXPLODE);
	}
}

//火焰喷发
public SkillFlameGushRY(target, userid)
{
	decl Float:pos[3];

	SkillBurnClaw(target, 2);
	GetClientAbsOrigin(userid, pos);
	LittleFlower(pos, MOLOTOV);
}
//地震技能调用
public Smash(client, target, Float:power, Float:powHor, Float:powVec)
{
	/* Blow off target */
	decl Float:HeadingVector[3], Float:AimVector[3];
	GetClientEyeAngles(client, HeadingVector);

	AimVector[0] = FloatMul(Cosine(DegToRad(HeadingVector[1])) ,power * powHor);
	AimVector[1] = FloatMul(Sine(DegToRad(HeadingVector[1])) ,power * powHor);

	decl Float:current[3];
	GetEntPropVector(target, Prop_Data, "m_vecVelocity", current);

	decl Float:resulting[3];
	resulting[0] = FloatAdd(current[0], AimVector[0]);
	resulting[1] = FloatAdd(current[1], AimVector[1]);
	resulting[2] = power * powVec;

	TeleportEntity(target, NULL_VECTOR, NULL_VECTOR, resulting);
}

//屏幕颜色
public ScreenFade(target, red, green, blue, alpha, duration, type)
{
	new Handle:msg = StartMessageOne("Fade", target);
	BfWriteShort(msg, 500);
	BfWriteShort(msg, duration);
	if (type == 0)
		BfWriteShort(msg, (0x0002 | 0x0008));
	else
		BfWriteShort(msg, (0x0001 | 0x0010));
	BfWriteByte(msg, red);
	BfWriteByte(msg, green);
	BfWriteByte(msg, blue);
	BfWriteByte(msg, alpha);
	EndMessage();
}

//屏幕震动
public ScreenShake(target, Float:intensity)
{
	new Handle:msg;
	msg = StartMessageOne("Shake", target);

	BfWriteByte(msg, 0);
	BfWriteFloat(msg, intensity);
	BfWriteFloat(msg, 10.0);
	BfWriteFloat(msg, 3.0);
	EndMessage();
}
/******************************************************
*	计时器子程序
*******************************************************/
//重力计时器
public Action:GravityTimer(Handle:timer, any:target)
{
	SetEntityGravity(target, 1.0);
	KillTimer(timer);
}


//致盲计时器
public Action:DreadTimer(Handle:timer, any:target)
{
	visibility -= 10;
	if(visibility < 0)  visibility = 0;
	ScreenFade(target, 0, 0, 0, visibility, 0, 1);
	if(visibility <= 0)
	{
		visibility = 0;
		ScreenFade(target, 0, 0, 0, 0, 0, 1);
		KillTimer(timer);
	}
}

/******************************************************
*	粒子控制子程序
*******************************************************/
/* 显示你想要的粒子效果 */
public ShowParticle(Float:pos[3], String:particlename[], Float:time)
{
	new particle = CreateEntityByName("info_particle_system");
	if (IsValidEdict(particle))
	{
		TeleportEntity(particle, pos, NULL_VECTOR, NULL_VECTOR);
		DispatchKeyValue(particle, "effect_name", particlename);
		DispatchKeyValue(particle, "targetname", "particle");
		DispatchSpawn(particle);
		ActivateEntity(particle);
		AcceptEntityInput(particle, "start");
		CreateTimer(time, DeleteParticles, particle);
	}
}
public Action:AttachParticle(target, String:particlename[], Float:time, Float:origin)
{
	if (target > 0 && IsValidEntity(target))
	{
   		new particle = CreateEntityByName("info_particle_system");
		if (IsValidEntity(particle))
		{
			new Float:pos[3];
			GetEntPropVector(target, Prop_Send, "m_vecOrigin", pos);
			pos[2] += origin;
			TeleportEntity(particle, pos, NULL_VECTOR, NULL_VECTOR);
			decl String:tName[64];
			Format(tName, sizeof(tName), "Attach%d", target);
			DispatchKeyValue(target, "targetname", tName);
			GetEntPropString(target, Prop_Data, "m_iName", tName, sizeof(tName));
			DispatchKeyValue(particle, "scale", "");
			DispatchKeyValue(particle, "effect_name", particlename);
			DispatchKeyValue(particle, "parentname", tName);
			DispatchKeyValue(particle, "targetname", "particle");
			DispatchSpawn(particle);
			ActivateEntity(particle);
			SetVariantString(tName);
			AcceptEntityInput(particle, "SetParent", particle, particle);
			AcceptEntityInput(particle, "Enable");
			AcceptEntityInput(particle, "start");
			CreateTimer(time, DeleteParticles, particle, TIMER_FLAG_NO_MAPCHANGE);
		}
	}
}
/* 预先缓存 */
public Action:PrecacheParticle(String:particlename[])
{
	new particle = CreateEntityByName("info_particle_system");
	if (IsValidEntity(particle))
	{
		DispatchKeyValue(particle, "effect_name", particlename);
		DispatchKeyValue(particle, "targetname", "particle");
		DispatchSpawn(particle);
		ActivateEntity(particle);
		AcceptEntityInput(particle, "start");
		CreateTimer(0.1, DeleteParticles, particle, TIMER_FLAG_NO_MAPCHANGE);
	}  
}
/* 删除粒子 */
public Action:DeleteParticles(Handle:timer, any:particle)
{
		if (IsValidEntity(particle))
	{
		new String:classname[64];
		GetEdictClassname(particle, classname, sizeof(classname));
		if (StrEqual(classname, "info_particle_system", false))
					AcceptEntityInput(particle, "Kill");
	}
}
//火焰爆炸效果
public LittleFlower(Float:pos[3], type)
{
	/* 火焰(type=0) 或 爆炸(type=1) */
	new entity = CreateEntityByName("prop_physics");
	if (IsValidEntity(entity))
	{
		pos[2] += 10.0;
		if (type == 0)
			/* fire */
			DispatchKeyValue(entity, "model", ENTITY_GASCAN);
		else
			/* explode */
			DispatchKeyValue(entity, "model", ENTITY_PROPANE);
		DispatchSpawn(entity);
		SetEntData(entity, GetEntSendPropOffs(entity, "m_CollisionGroup"), 1, 1, true);
		TeleportEntity(entity, pos, NULL_VECTOR, NULL_VECTOR);
		AcceptEntityInput(entity, "break");
	}
}
public PerformFade(client, duration, unknown, type1, type2, const Color[4]) 
{
	switch(type1)
	{
		case 1: type1 = FFADE_IN;
		case 2: type1 = FFADE_OUT;
		case 4: type1 = FFADE_MODULATE;
		case 8: type1 = FFADE_STAYOUT;
		case 10: type1 = FFADE_PURGE;
	}
	switch(type2)
	{
		case 1: type2 = FFADE_IN;
		case 2: type2 = FFADE_OUT;
		case 4: type2 = FFADE_MODULATE;
		case 8: type2 = FFADE_STAYOUT;
		case 10: type2 = FFADE_PURGE;
	}
	new Handle:hFadeClient=StartMessageOne("Fade", client);
	BfWriteShort(hFadeClient, duration);
	BfWriteShort(hFadeClient, unknown);
	BfWriteShort(hFadeClient, (type1|type2));
	BfWriteByte(hFadeClient, Color[0]);
	BfWriteByte(hFadeClient, Color[1]);
	BfWriteByte(hFadeClient, Color[2]);
	BfWriteByte(hFadeClient, Color[3]);
	EndMessage();
}
// 仍石头属性
public Action:RockThrowTimer(Handle:timer)
{
	new entity = -1;
	while ((entity = FindEntityByClassname(entity, "tank_rock")) != INVALID_ENT_REFERENCE)
	{
		new thrower = GetEntPropEnt(entity, Prop_Data, "m_hThrower");
		if (IsTank(thrower) && !bIsDoubleTankSpawn[thrower])
		{
			switch(tanktype[thrower])
			{
				// 烈焰
				case TANK_Fire:
				{
	  	 			SetEntityRenderColor(entity, 128, 0, 0, 255);
					CreateTimer(0.8, Timer_AttachFIRE_Rock, entity, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
				}
				// 冰霜
				case TANK_Ice:
				{
					SetEntityRenderMode(entity, RenderMode:3);
					SetEntityRenderColor(entity, 0, 100, 170, 180);
				}
				// 猴子
				case TANK_Jockey:
				{
					Rock[thrower] = entity;
					CreateTimer(0.1, JockeyThrow, thrower, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
				}
				// 酸液
				case TANK_Spitter:
				{
					SetEntityRenderMode(entity, RenderMode:3);
	  	 			SetEntityRenderColor(entity, 121, 151, 28, 30);
					CreateTimer(0.8, Timer_SpitSound, thrower, TIMER_FLAG_NO_MAPCHANGE);	// 声效
					CreateTimer(0.8, Timer_AttachSPIT_Rock, entity, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);  // 渲染石头
				}
				// 闪电
				case TANK_Shock:
				{
					CreateTimer(0.8, Timer_AttachELEC_Rock, entity, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
				}
				// 护盾
				case TANK_Shield:
				{
					Rock[thrower] = entity;
					CreateTimer(0.1, PropaneThrow, thrower, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
				}
			}
		}
	}
}
// 护盾
public Action:PropaneThrow(Handle:timer, any:client)
{
	new Float:velocity[3];
	new entity = Rock[client];
	if (IsValidEntity(entity))
	{
		new g_iVelocity = FindSendPropOffs("CBasePlayer", "m_vecVelocity[0]");	
		GetEntDataVector(entity, g_iVelocity, velocity);
		new Float:v = GetVectorLength(velocity);
		if (v > 500.0)
		{
			new propane = CreateEntityByName("prop_physics");
			if (IsValidEntity(propane))
			{
				DispatchKeyValue(propane, "model", "models/props_junk/propanecanister001a.mdl");
				DispatchSpawn(propane);
				new Float:Pos[3];
				GetEntPropVector(entity, Prop_Send, "m_vecOrigin", Pos);	
				AcceptEntityInput(entity, "Kill");
				NormalizeVector(velocity, velocity);
				new Float:speed = GetConVarFloat(FindConVar("z_tank_throw_force"));
				ScaleVector(velocity, speed*1.4);
				TeleportEntity(propane, Pos, NULL_VECTOR, velocity);
			}	
			return Plugin_Stop;
		}		
	}
	else
	{
		return Plugin_Stop;
	}
	return Plugin_Continue;
}
// 猴子
public Action:JockeyThrow(Handle:timer, any:client)
{
	new Float:velocity[3];
	new entity = Rock[client];
	if (IsValidEntity(entity))
	{
		new g_iVelocity = FindSendPropOffs("CBasePlayer", "m_vecVelocity[0]");	
		GetEntDataVector(entity, g_iVelocity, velocity);
		new Float:v = GetVectorLength(velocity);
		if (v > 500.0)
		{
			new bot = CreateFakeClient("Jockey");
			if (bot > 0)
			{
				SpawnInfected(bot, 5, true);
				new Float:Pos[3];
				GetEntPropVector(entity, Prop_Send, "m_vecOrigin", Pos);	
				AcceptEntityInput(entity, "Kill");
				NormalizeVector(velocity, velocity);
				new Float:speed = GetConVarFloat(FindConVar("z_tank_throw_force"));
				ScaleVector(velocity, speed*1.4);
				TeleportEntity(bot, Pos, NULL_VECTOR, velocity);
			}	
			return Plugin_Stop;
		}		
	}
	else
	{
		return Plugin_Stop;
	}
	return Plugin_Continue;
}
// 忍者tank传送
public Action:RenZheTankTimer(Handle:timer, any:client)
{
	// 获取当前坐标
		new Float:angleSaves[MAXPLAYERS+1][3];
		new Float:angleEyes[MAXPLAYERS+1][3];
		new Float:number = 1000.0;
		GetClientAbsAngles(client, angleSaves[client]);
		GetClientEyeAngles(client, angleEyes[client]);
		new Float:number_x = number * Cosine(angleSaves[client][1] * 3.14159 / 180.0);
		new Float:number_y = number * Sine(angleSaves[client][1] * 3.14159 / 180.0);
		//new Float:number_z = -number * Sine(angleEyes[client][0] * 3.14159 / 180.0);
		
		//PrintToChat(client, "玩家坐标数据 <%f, %f, %f>，角度数据<%f, %f, %f>!", number_x, number_y, number_z, angleSaves[client][0], angleSaves[client][1], angleSaves[client][2]);
		
		new Float:vecVelocity[3];
		GetEntPropVector(client, Prop_Data, "m_vecVelocity", vecVelocity);
		
		vecVelocity[0] += number_x;
		vecVelocity[1] += number_y;
		//vecVelocity[2] += number_z
		// 移动到位置
		// 视觉
		angleSaves[client][1] += 180.0;
		//TeleportEntity(client, originSaves[client], angleSaves[client], NULL_VECTOR); 
		TeleportEntity(client, NULL_VECTOR, angleSaves[client], vecVelocity);
}
// 跳跃
public Action:JumpTimer(Handle:timer, any:client)
{
	if (client > 0 && IsTank(client))
	{
		new flags = GetEntityFlags(client);
		if (flags & FL_ONGROUND)
		{

			if (GetNearestSurvivorDist(client) > 200 && GetNearestSurvivorDist(client) < 2000)
			{
				FakeJump(client);
			}
		}
		return Plugin_Continue;
	}
	return Plugin_Stop;
}
public FakeJump(client)
{
	//CPrintToChatAll("FakeJump___%N", client);
	if (IsTank(client))
	{
		//CPrintToChatAll("IsTank  %N", client);
		// 获取当前坐标
		new Float:angleSaves[MAXPLAYERS+1][3];
		new Float:angleEyes[MAXPLAYERS+1][3];
		new Float:number = 500.0;
		GetClientAbsAngles(client, angleSaves[client]);
		GetClientEyeAngles(client, angleEyes[client]);
		new Float:number_x = number * Cosine(angleSaves[client][1] * 3.14159 / 180.0);
		new Float:number_y = number * Sine(angleSaves[client][1] * 3.14159 / 180.0);
		//new Float:number_z = -number * Sine(angleEyes[client][0] * 3.14159 / 180.0);
		
		//PrintToChat(client, "玩家坐标数据 <%f, %f, %f>，角度数据<%f, %f, %f>!", number_x, number_y, number_z, angleSaves[client][0], angleSaves[client][1], angleSaves[client][2]);
		
		new Float:vecVelocity[3];
		GetEntPropVector(client, Prop_Data, "m_vecVelocity", vecVelocity);
				
		vecVelocity[0] += number_x;
		vecVelocity[1] += number_y;
		//vecVelocity[2] += number_z;
		
	   //PrintToChat(client, "玩家坐标数据 <%f, %f, %f>，角度数据<%f, %f, %f>!", number_x, number_y, number_z, angleSaves[client][0], angleSaves[client][1], angleSaves[client][2]);
		// 移动到位置
		//TeleportEntity(client, originSaves[client], angleSaves[client], NULL_VECTOR);
		vecVelocity[2] += 800.0;	  
		TeleportEntity(client, NULL_VECTOR, NULL_VECTOR, vecVelocity);
		
		//CPrintToChatAll("TeleportEntity  %N", client);
	}
}
public SkillFlameClaw(target)
{
	if (target > 0)
	{
		if (IsClientInGame(target) && IsPlayerAlive(target) && GetClientTeam(target) == 2)
		{
			IgniteEntity(target, 3.0);
			EmitSoundToAll("ambient/fire/gascan_ignite1.wav", target);
			PerformFade(target, 500, 250, 10, 1, {100, 50, 0, 150});
		}
	}
}
public SkillIceClaw(target)
{
	if (target > 0)
	{
		if (IsClientInGame(target) && IsPlayerAlive(target) && GetClientTeam(target) == 2)
		{
			SetEntityRenderMode(target, RenderMode:3);
			SetEntityRenderColor(target, 0, 100, 170, 180);
			SetEntityMoveType(target, MOVETYPE_NONE);
			CreateTimer(fIceNotMoveTimes, Timer_UnFreeze, target, TIMER_FLAG_NO_MAPCHANGE); // 冰冻后多久解冻
			PerformFade(target, 500, 250, 10, 1, {0, 50, 100, 150});
		}
	}
}
public SkillFlameGush(target)
{
	if (target > 0)
	{
		if (IsClientInGame(target) && IsPlayerAlive(target) && GetClientTeam(target) == 3)
		{
			decl Float:pos[3];
			GetClientAbsOrigin(target, pos);
			new entity = CreateEntityByName("prop_physics");
			if (IsValidEntity(entity))
			{
				pos[2] += 10.0;
				DispatchKeyValue(entity, "model", "models/props_junk/gascan001a.mdl");
				DispatchSpawn(entity);
				SetEntData(entity, GetEntSendPropOffs(entity, "m_CollisionGroup"), 1, 1, true);
				TeleportEntity(entity, pos, NULL_VECTOR, NULL_VECTOR);
				AcceptEntityInput(entity, "break");
			}
		}
	}
}
public SkillGravityClaw(target)
{
	if (target > 0)
	{
		if (IsClientInGame(target) && IsPlayerAlive(target) && GetClientTeam(target) == 2)
		{
			SetEntityGravity(target, 0.3);
			CreateTimer(2.0, Timer_ResetGravity, target, TIMER_FLAG_NO_MAPCHANGE);
			PerformFade(target, 500, 250, 10, 1, {100, 50, 100, 150});
			ScreenShake(target, 5.0);
		}
	}
}
// 陨石tank产生属性
public Action:MeteorTankTimer(Handle:timer, any:client)
{
	if (client > 0 && IsTank(client))
	{		
		if (tanktype[client] == TANK_Meteor)
		{
			new Float:Origin[3], Float:Angles[3];
			GetEntPropVector(client, Prop_Send, "m_vecOrigin", Origin);
			GetEntPropVector(client, Prop_Send, "m_angRotation", Angles);
			new ent[5];
			for (new count=1; count<=4; count++)
			{
				ent[count] = CreateEntityByName("prop_dynamic_override");
				if (IsValidEntity(ent[count]))
				{
					decl String:tName[64];
					Format(tName, sizeof(tName), "Tank%d", client);
					DispatchKeyValue(client, "targetname", tName);
					GetEntPropString(client, Prop_Data, "m_iName", tName, sizeof(tName));
					DispatchKeyValue(ent[count], "model", "models/props_debris/concrete_chunk01a.mdl");
					DispatchKeyValue(ent[count], "targetname", "RockEntity");
					DispatchKeyValue(ent[count], "parentname", tName);
					DispatchKeyValueVector(ent[count], "origin", Origin);
					DispatchKeyValueVector(ent[count], "angles", Angles);
					DispatchSpawn(ent[count]);
					SetVariantString(tName);
					AcceptEntityInput(ent[count], "SetParent", ent[count], ent[count]);
					switch(count)
					{
						case 1:SetVariantString("relbow");
						case 2:SetVariantString("lelbow");
						case 3:SetVariantString("rshoulder");
						case 4:SetVariantString("lshoulder");
					}
					AcceptEntityInput(ent[count], "SetParentAttachment");
					AcceptEntityInput(ent[count], "Enable");
					AcceptEntityInput(ent[count], "DisableCollision");
					switch(count)
					{
						case 1,2:SetEntPropFloat(ent[count], Prop_Data, "m_flModelScale", 0.4);
						case 3,4:SetEntPropFloat(ent[count], Prop_Data, "m_flModelScale", 0.5);
					}
					SetEntProp(ent[count], Prop_Send, "m_hOwnerEntity", client);
					Angles[0] = Angles[0] + GetRandomFloat(-90.0, 90.0);
					Angles[1] = Angles[1] + GetRandomFloat(-90.0, 90.0);
					Angles[2] = Angles[2] + GetRandomFloat(-90.0, 90.0);
					TeleportEntity(ent[count], NULL_VECTOR, Angles, NULL_VECTOR);
				}
			}
		}
	}
}
// 跳跃tank产生属性
public Action:JumperTankTimer(Handle:timer, any:client)
{
	if (client > 0 && IsTank(client))
	{		
		if (tanktype[client] == TANK_Jumper)
		{
			new Float:Origin[3], Float:Angles[3];
			GetEntPropVector(client, Prop_Send, "m_vecOrigin", Origin);
			GetEntPropVector(client, Prop_Send, "m_angRotation", Angles);
			Angles[0] += 90.0;
			new ent[3];
			for (new count=1; count<=2; count++)
			{
				ent[count] = CreateEntityByName("prop_dynamic_override");
				if (IsValidEntity(ent[count]))
				{
					decl String:tName[64];
					Format(tName, sizeof(tName), "Tank%d", client);
					DispatchKeyValue(client, "targetname", tName);
					GetEntPropString(client, Prop_Data, "m_iName", tName, sizeof(tName));

					DispatchKeyValue(ent[count], "model", "models/props_vehicles/tire001c_car.mdl");
					DispatchKeyValue(ent[count], "targetname", "TireEntity");
					DispatchKeyValue(ent[count], "parentname", tName);
					DispatchKeyValueVector(ent[count], "origin", Origin);
					DispatchKeyValueVector(ent[count], "angles", Angles);
					DispatchSpawn(ent[count]);
					SetVariantString(tName);
					AcceptEntityInput(ent[count], "SetParent", ent[count], ent[count]);
					switch(count)
					{
						case 1:SetVariantString("rfoot");
						case 2:SetVariantString("lfoot");
					}
					AcceptEntityInput(ent[count], "SetParentAttachment");
					AcceptEntityInput(ent[count], "Enable");
					AcceptEntityInput(ent[count], "DisableCollision");
					SetEntProp(ent[count], Prop_Send, "m_hOwnerEntity", client);
					TeleportEntity(ent[count], NULL_VECTOR, Angles, NULL_VECTOR);
				}
			}
		}
	}
}
// 磁力tank附加属性
public Action:GravityTankTimer(Handle:timer, any:client)
{
	if (IsTank(client))
	{
		if (tanktype[client] == TANK_Gravity)
		{
			new Float:Origin[3], Float:Angles[3];
			GetEntPropVector(client, Prop_Send, "m_vecOrigin", Origin);
			GetEntPropVector(client, Prop_Send, "m_angRotation", Angles);
			Angles[0] += -90.0;
			new entity = CreateEntityByName("beam_spotlight"); // 聚光灯
			if (IsValidEntity(entity))
			{
				decl String:tName[64];
				Format(tName, sizeof(tName), "Tank%d", client);
				DispatchKeyValue(client, "targetname", tName);
				GetEntPropString(client, Prop_Data, "m_iName", tName, sizeof(tName));

				DispatchKeyValue(entity, "targetname", "LightEntity");
				DispatchKeyValue(entity, "parentname", tName);
				DispatchKeyValueVector(entity, "origin", Origin);
				DispatchKeyValueVector(entity, "angles", Angles);
				DispatchKeyValue(entity, "spotlightwidth", "10");
				DispatchKeyValue(entity, "spotlightlength", "60");
				DispatchKeyValue(entity, "spawnflags", "3");
				DispatchKeyValue(entity, "rendercolor", "100 100 100");
				DispatchKeyValue(entity, "renderamt", "125");
				DispatchKeyValue(entity, "maxspeed", "100");
				DispatchKeyValue(entity, "HDRColorScale", "0.7");
				DispatchKeyValue(entity, "fadescale", "1");
				DispatchKeyValue(entity, "fademindist", "-1");
				DispatchSpawn(entity);
				SetVariantString(tName);
				AcceptEntityInput(entity, "SetParent", entity, entity);
				SetVariantString("mouth");
				AcceptEntityInput(entity, "SetParentAttachment");
				AcceptEntityInput(entity, "Enable");
				AcceptEntityInput(entity, "DisableCollision");
				SetEntProp(entity, Prop_Send, "m_hOwnerEntity", client);
				TeleportEntity(entity, NULL_VECTOR, Angles, NULL_VECTOR);
			}
			new blackhole = CreateEntityByName("point_push");   // 磁力吸附
			if (IsValidEntity(blackhole))
			{
				decl String:tName[64];
				Format(tName, sizeof(tName), "Tank%d", client);
				DispatchKeyValue(client, "targetname", tName);
				GetEntPropString(client, Prop_Data, "m_iName", tName, sizeof(tName));

				DispatchKeyValue(blackhole, "targetname", "BlackholeEntity");
				DispatchKeyValue(blackhole, "parentname", tName);
                CPrintToChatAll("tName %s", tName);
                // 不磁力特感
                for (new i=1; i<=MaxClients; i++)
                {
                    if(IsValidPlayer(i) && GetClientTeam(i) == 3)
                    {
                        decl String:sInfName[64];
                        GetEntPropString(i, Prop_Data, "m_iName", sInfName, sizeof(sInfName));
                        DispatchKeyValue(blackhole, "parentname", sInfName);
                        //CPrintToChatAll("sInfName %s", sInfName);
                    }
                }
                //
				DispatchKeyValueVector(blackhole, "origin", Origin);
				DispatchKeyValueVector(blackhole, "angles", Angles);
				decl String:sradiiyard[64];
				Format(sradiiyard, sizeof(sradiiyard), "%d", g_iGravityRadiiYard);
				DispatchKeyValue(blackhole, "radius", sradiiyard);
				DispatchKeyValueFloat(blackhole, "magnitude", flGravityPullForce);
				DispatchKeyValue(blackhole, "spawnflags", "8");// 磁力作用类型
				SetVariantString(tName);
				AcceptEntityInput(blackhole, "SetParent", blackhole, blackhole);
                //
                //
				AcceptEntityInput(blackhole, "Enable");
				SetEntProp(blackhole, Prop_Send, "m_glowColorOverride", client);
			}
		}
	}
}
// 磁力tank附加属性，自定义吸附，排除感染者，直接坐标更换
public Action:GravityTankTimerEx(Handle:timer, any:client)
{
    if (IsTank(client) && tanktype[client] == TANK_Gravity)
	{
        //new Float:vecVelocity[3];   // 传送临时坐标
        //GetEntPropVector(client, Prop_Data, "m_vecVelocity", vecVelocity);
        new Float:clientPos[3];// tank位置
        new Float:TempPos[3];   // 玩家位置
        new Float:PosX, Float:PosY, Float:XYDistance; // 相对坐标，tank相对于玩家，玩家为坐标零点
        new Float:fMoveX, Float:fMoveY;     // 移动坐标数据
        new Float:angleSaves[3];
        // 获取tank位置
        GetClientAbsOrigin(client, clientPos);
        for( new i = 1; i <= MaxClients; i++ ) 
        {
            if(IsValidPlayer(i) && GetClientTeam(i) == 2 && i != client)
            {
                GetClientAbsOrigin(i, TempPos);
                XYDistance = GetVectorDistance(clientPos, TempPos);
                if(XYDistance < g_iGravityRadiiYard)
                {
                    // 获得相对坐标
                    PosX = clientPos[0] - TempPos[0];
                    PosY = clientPos[1] - TempPos[1];
                    // 获得移动坐标数据
                    fMoveX = PosX * g_fGravityFreqYard / XYDistance;
                    fMoveY = PosY * g_fGravityFreqYard / XYDistance;
                    
                    TempPos[0] += fMoveX;
                    TempPos[1] += fMoveY;
                    // 坐标传送
                    GetClientAbsAngles(i, angleSaves);
                    TeleportEntity(i, NULL_VECTOR, angleSaves, TempPos); // 移动，不穿过阻碍物
                }
            }
        }
    }
    
}
// 分身tank
public Action:DoubleTankTimer(Handle:timer, any:maxhealth)
{
	for(new i = 0; i < iDoubleTankCounts; i++)
	{
		new random_client = GetRandomPlayer(3);
		if(!bIsDoubleTankSpawn[random_client])
		{
			bIsDoubleTankSpawn[random_client] = true;
			//
			new flags = GetCommandFlags("z_spawn");
			SetCommandFlags("z_spawn", flags & ~FCVAR_CHEAT);
			FakeClientCommand(random_client, "z_spawn tank auto")
			SetCommandFlags("z_spawn", flags);	
			//		
			CPrintToChatAll("{green}玩家{lightgreen}【%N】{green}获得分身坦克: {green} 生命值: {lightgreen}%d  {green}移动倍数: {lightgreen}%.2f ", random_client, iTankExtraHealth[TANK_Double], flTankSpeed[TANK_Double]);
		}		
	}	
}
public SetDoubleTankValue(client)
{
	// 生命
	new maxhealth = GetConVarInt(hDoubleExtraHealth);
	SetEntProp(client, Prop_Data, "m_iMaxHealth", maxhealth);
	SetEntProp(client, Prop_Data, "m_iHealth", maxhealth);
	// 速度
    SetEntDataFloat(client, g_iLaggedMovementO, GetConVarFloat(hDoubleSpeed), true);		
	ClientCommand(client, "sm_buy");		//修复8分健康BUG的利用		
}
// 暴走tank, 设置感染CD为暴走CD
public Action:AdrenalTankTimer(Handle:timer, any:client)
{
	for (new i=1; i<=MaxClients; i++)
	{
		if(IsValidPlayer(i) && GetClientTeam(i) == 3)
		{
			ResetInfectedAbility(i, flTankThrow[TANK_Adrenal]);
		}
	}
}

public Action:BlurEffect(Handle:timer, any:client)
{
	if (IsTank(client) && iMoveCobaltBeginTimeFlag[client])
	{
		new Float:TankPos[3], Float:TankAng[3];
		GetClientAbsOrigin(client, TankPos);
		GetClientAbsAngles(client, TankAng);
		new Anim = GetEntProp(client, Prop_Send, "m_nSequence");
		new entity = CreateEntityByName("prop_dynamic");
		if (IsValidEntity(entity))
		{
			DispatchKeyValue(entity, "model", "models/infected/hulk.mdl");
			DispatchKeyValue(entity, "solid", "6");
			DispatchSpawn(entity);
			AcceptEntityInput(entity, "DisableCollision");
			SetEntityRenderColor(entity, 0, 105, 255, 255);
			SetEntProp(entity, Prop_Send, "m_nSequence", Anim);
			SetEntPropFloat(entity, Prop_Send, "m_flPlaybackRate", 15.0);
			TeleportEntity(entity, TankPos, TankAng, NULL_VECTOR);
			CreateTimer(0.3, RemoveBlurEffect, entity, TIMER_FLAG_NO_MAPCHANGE);
			return Plugin_Continue;
		}		
	}
	return Plugin_Stop;
}
public Action:RemoveBlurEffect(Handle:timer, any:entity)
{
	if (IsValidEntity(entity))
	{
		decl String:classname[32];
		GetEdictClassname(entity, classname, sizeof(classname));
		if (StrEqual(classname, "prop_dynamic"))
		{
			decl String:model[128];
			GetEntPropString(entity, Prop_Data, "m_ModelName", model, sizeof(model));
			if (StrEqual(model, "models/infected/hulk.mdl"))
			{
				AcceptEntityInput(entity, "Kill");
			}
		}	
	}
}
public SkillSmashClaw(target)
{
	new health = GetEntProp(target, Prop_Data, "m_iHealth");
	if (health > 1 && !IsPlayerIncap(target))
	{
		SetEntProp(target, Prop_Data, "m_iHealth", iSmasherMaimDamage);
		new Float:hbuffer = float(health) - float(iSmasherMaimDamage);
		if (hbuffer > 0.0)
		{
			SetEntPropFloat(target, Prop_Send, "m_healthBuffer", hbuffer);
		}
	}
	EmitSoundToAll("player/charger/hit/charger_smash_02.wav", target);
	PerformFade(target, 800, 300, 10, 1, {10, 0, 0, 250});
	ScreenShake(target, 30.0);
}
public SkillSmashClawKill(client, attacker)
{
	EmitSoundToAll("player/tank/voice/growl/tank_climb_01.wav", attacker);
	AttachParticle(client, PARTICLE_EXPLODE, 0.1, 0.0);
	DealDamagePlayer(client, attacker, 2, iSmasherCrushDamage);
	DealDamagePlayer(client, attacker, 2, iSmasherCrushDamage);
	CreateTimer(0.1, RemoveDeathBody, client, TIMER_FLAG_NO_MAPCHANGE);
}
public Action:RemoveDeathBody(Handle:timer, any:client)
{
	if (bSmasherRemoveBody)
	{
		if (client > 0)
		{
			if (IsClientInGame(client) && GetClientTeam(client) == 2)
			{
				new entity = -1;
				while ((entity = FindEntityByClassname(entity, "survivor_death_model")) != INVALID_ENT_REFERENCE)
				{
					new owner = GetEntPropEnt(entity, Prop_Send, "m_hOwnerEntity");
					if (client == owner)
					{
						AcceptEntityInput(entity, "Kill");
					}
				}
			}
		}
	}
}
// 闪电至晕，随机方向
public SkillElecClawEx(client)
{
	if(IsValidPlayer(client) && GetClientTeam(client) == 2)
	{
		new Float:Angles[3];
		GetClientAbsAngles(client, Angles);
		//new Float:AnglesEye[3];		
		//GetClientEyeAngles(client, AnglesEye);  		
		//CPrintToChatAll("angle %f__%f__%f", Angles[0], Angles[1], Angles[2]);
		Angles[0] = GetRandomFloat(-180.0, 180.0);
		Angles[1] = GetRandomFloat(-180.0, 180.0);
		Angles[2] = GetRandomFloat(-180.0, 180.0);
	
		TeleportEntity(client, NULL_VECTOR, Angles, NULL_VECTOR);
		
		//CreateTimer(g_fSkillViewTime, RemoveSkillView, client, TIMER_FLAG_NO_MAPCHANGE);
	}
}

public Action:RemoveSkillView(Handle:timer, any:client)
{
	CreateTimer(0.8, RemovSkillBlack1, client);	// 白屏屏
	EmitSoundToAll(SOUND_DCLAW, client);
	ScreenFade(client, 0, 0, 0, 0, 0, 0);
}
public RemoveSkillViewEx(client)
{
    CreateTimer(0.8, RemovSkillBlack1, client);	// 白屏屏
	EmitSoundToAll(SOUND_DCLAW, client);
	ScreenFade(client, 0, 0, 0, 0, 0, 0);
}
//致盲计时器
public Action:RemovSkillBlack1(Handle:timer, any:client)
{
	ScreenFade(client, 0, 0, 0, 252, 0, 1);	
	CreateTimer(0.8, RemovSkillBlack, client);	// 黑屏开始
    
	new Float:Angles[3];                    // 视觉纠正
	GetClientAbsAngles(client, Angles);
	Angles[0] = 0.0;
	//Angles[1] = GetRandomFloat(-180.0, 180.0);
	Angles[2] = 0.0;			  
	TeleportEntity(client, NULL_VECTOR, Angles, NULL_VECTOR);
}

//致盲计时器
public Action:RemovSkillBlack(Handle:timer, any:client)
{
	ScreenFade(client, 0, 0, 0, 0, 0, 1);		    // 白屏
}
// 闪电减速
public SkillElecClaw(target, tank)
{
	if (target > 0)
	{
		if (IsClientInGame(target) && IsPlayerAlive(target) && GetClientTeam(target) == 2)
		{
			PlayerSpeed[target] += 3;
			new Handle:Pack = CreateDataPack();
			WritePackCell(Pack, target);
			WritePackCell(Pack, tank);
			WritePackCell(Pack, 4);
			CreateTimer(0.1, Timer_Volt, Pack, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
			PerformFade(target, 250, 100, 10, 1, {50, 150, 250, 100});
			ScreenShake(target, 15.0);
			AttachParticle(target, PARTICLE_ELEC, 2.0, 30.0);
			EmitSoundToAll("ambient/energy/zap1.wav", target);
		}
	}
}
public Action:Timer_Volt(Handle:timer, any:Pack)
{
	ResetPack(Pack, false);
	new client = ReadPackCell(Pack);
	new tank = ReadPackCell(Pack);
	new amount = ReadPackCell(Pack);

	if (client > 0 && tank > 0)
	{
		if (IsClientInGame(client) && IsPlayerAlive(client) && GetClientTeam(client) == 2 && PlayerSpeed[client] == 0 && IsTank(tank))
		{
			if (amount > 0)
			{
				PlayerSpeed[client] += 2;
				ScreenShake(client, 2.0);
				DealDamagePlayer(client, tank, 2, iShockStunDamage);
				AttachParticle(client, PARTICLE_ELEC, 2.0, 30.0);
				new random = GetRandomInt(1,2);
				if (random == 1) 
				{
					EmitSoundToAll("ambient/energy/zap5.wav", client);
				}
				else
				{
					EmitSoundToAll("ambient/energy/zap7.wav", client);
				}
				ResetPack(Pack, true);
				WritePackCell(Pack, client);
				WritePackCell(Pack, tank);
				WritePackCell(Pack, amount - 1);
				return Plugin_Continue;
			}
		}
	}
	CloseHandle(Pack);
	return Plugin_Stop;
}
StartMeteorFall(client)
{
	TankAbility[client] = 1;
	decl Float:pos[3];
	GetClientEyePosition(client, pos);
	
	new Handle:h=CreateDataPack();
	WritePackCell(h, client);
	WritePackFloat(h, pos[0]);
	WritePackFloat(h, pos[1]);
	WritePackFloat(h, pos[2]);
	WritePackFloat(h, GetEngineTime());
	
	CreateTimer(fMeteorStormDelay, UpdateMeteorFall, h, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
	//CreateTimer(0.6, UpdateMeteorFall, h, TIMER_FLAG_NO_MAPCHANGE);
}

public Action:UpdateMeteorFall(Handle:timer, any:h)
{
	ResetPack(h);
	decl Float:pos[3];
	new client = ReadPackCell(h);
 	
	pos[0] = ReadPackFloat(h);
	pos[1] = ReadPackFloat(h);
	pos[2] = ReadPackFloat(h);

	new Float:time = ReadPackFloat(h);
	if ((GetEngineTime() - time) > 5.0)
	{
		TankAbility[client] = 0;
	}
	new entity = -1;
	if (IsTank(client) && TankAbility[client] == 1)
	{
		decl Float:angle[3], Float:velocity[3], Float:hitpos[3];
		angle[0] = 0.0 + GetRandomFloat(-20.0, 20.0);
		angle[1] = 0.0 + GetRandomFloat(-20.0, 20.0);
		angle[2] = 60.0;
		
		GetVectorAngles(angle, angle);
		GetRayHitPos(pos, angle, hitpos, client, true);
		new Float:dis = GetVectorDistance(pos, hitpos);
		if (GetVectorDistance(pos, hitpos) > 1300.0)
		{
			dis = 1300.0;
		}
		decl Float:t[3];
		MakeVectorFromPoints(pos, hitpos, t);
		NormalizeVector(t,t);
		ScaleVector(t, dis - 40.0);
		AddVectors(pos, t, hitpos);
		
		if (dis > 100.0)
		{
			new ent = CreateEntityByName("tank_rock");
			if (ent > 0)
			{
				DispatchKeyValue(ent, "model", "models/props_debris/concrete_chunk01a.mdl"); 
				DispatchSpawn(ent);  
				decl Float:angle2[3];
				angle2[0] = GetRandomFloat(-180.0, 180.0);
				angle2[1] = GetRandomFloat(-180.0, 180.0);
				angle2[2] = GetRandomFloat(-180.0, 180.0);

				velocity[0] = GetRandomFloat(0.0, 350.0);
				velocity[1] = GetRandomFloat(0.0, 350.0);
				velocity[2] = GetRandomFloat(0.0, 30.0);

				TeleportEntity(ent, hitpos, angle2, velocity);
				ActivateEntity(ent);
	 
				AcceptEntityInput(ent, "Ignite");
				SetEntProp(ent, Prop_Send, "m_hOwnerEntity", client);
			}
		} 
	}
	else if (TankAbility[client] == 0)
	{
		while ((entity = FindEntityByClassname(entity, "tank_rock")) != INVALID_ENT_REFERENCE)
		{
			new ownerent = GetEntProp(entity, Prop_Send, "m_hOwnerEntity");
			if (client == ownerent)
			{
				ExplodeMeteor(entity, ownerent);
			}
		}
		CloseHandle(h);
		return Plugin_Stop;
	}
	while ((entity = FindEntityByClassname(entity, "tank_rock")) != INVALID_ENT_REFERENCE)
	{
		new ownerent = GetEntProp(entity, Prop_Send, "m_hOwnerEntity");
		if (client == ownerent)
		{
			if (OnGroundUnits(entity) < 200.0)
			{
				ExplodeMeteor(entity, ownerent);
			}
		}
	}
	return Plugin_Continue;	
}
public Float:OnGroundUnits(i_Ent)
{
	if (!(GetEntityFlags(i_Ent) & (FL_ONGROUND)))
	{ 
		decl Handle:h_Trace, Float:f_Origin[3], Float:f_Position[3], Float:f_Down[3] = { 90.0, 0.0, 0.0 };
		
		GetEntPropVector(i_Ent, Prop_Send, "m_vecOrigin", f_Origin);
		h_Trace = TR_TraceRayFilterEx(f_Origin, f_Down, CONTENTS_SOLID|CONTENTS_MOVEABLE, RayType_Infinite, TraceRayDontHitSelfAndLive, i_Ent);

		if (TR_DidHit(h_Trace))
		{
			decl Float:f_Units;
			TR_GetEndPosition(f_Position, h_Trace);
			
			f_Units = f_Origin[2] - f_Position[2];

			CloseHandle(h_Trace);
			
			return f_Units;
		}
		CloseHandle(h_Trace);
	} 
	
	return 0.0;
}
stock GetRayHitPos(Float:pos[3], Float:angle[3], Float:hitpos[3], ent=0, bool:useoffset=false)
{
	new Handle:trace;
	new hit=0;
	
	trace= TR_TraceRayFilterEx(pos, angle, MASK_SOLID, RayType_Infinite, TraceRayDontHitSelfAndLive, ent);
	if (TR_DidHit(trace))
	{
		TR_GetEndPosition(hitpos, trace);
		hit=TR_GetEntityIndex( trace);
	}
	CloseHandle(trace);
	
	if (useoffset)
	{
		decl Float:v[3];
		MakeVectorFromPoints(hitpos, pos, v);
		NormalizeVector(v, v);
		ScaleVector(v, 15.0);
		AddVectors(hitpos, v, hitpos);
	}
	return hit;
}
stock ExplodeMeteor(entity, client)
{
	if (IsValidEntity(entity))
	{
		decl String:classname[20];
		GetEdictClassname(entity, classname, 20);
		if (!StrEqual(classname, "tank_rock", true))
		{
			return;
		}

		new Float:pos[3];
		GetEntPropVector(entity, Prop_Send, "m_vecOrigin", pos);	
		pos[2]+=50.0;
		AcceptEntityInput(entity, "Kill");
	
		new ent = CreateEntityByName("prop_physics"); 		
		DispatchKeyValue(ent, "model", "models/props_junk/propanecanister001a.mdl"); 
		DispatchSpawn(ent); 
		TeleportEntity(ent, pos, NULL_VECTOR, NULL_VECTOR);
		ActivateEntity(ent);
		AcceptEntityInput(ent, "Break");

		new pointHurt = CreateEntityByName("point_hurt");   
		DispatchKeyValueFloat(pointHurt, "Damage", flMeteorStormDamage);	 
		DispatchKeyValue(pointHurt, "DamageType", "2");  
		DispatchKeyValue(pointHurt, "DamageDelay", "0.0");
		DispatchKeyValueFloat(pointHurt, "DamageRadius", 200.0);  
		DispatchSpawn(pointHurt);
		TeleportEntity(pointHurt, pos, NULL_VECTOR, NULL_VECTOR);  
		AcceptEntityInput(pointHurt, "Hurt", client);	
		CreateTimer(0.1, DeletePointHurt, pointHurt, TIMER_FLAG_NO_MAPCHANGE); 
		
		new push = CreateEntityByName("point_push");		 
  		DispatchKeyValueFloat (push, "magnitude", 600.0);					 
		DispatchKeyValueFloat (push, "radius", 200.0*1.0);					 
  		SetVariantString("spawnflags 24");					 
		AcceptEntityInput(push, "AddOutput");
 		DispatchSpawn(push);   
		TeleportEntity(push, pos, NULL_VECTOR, NULL_VECTOR);  
 		AcceptEntityInput(push, "Enable", -1, -1);
		CreateTimer(0.5, DeletePushForce, push, TIMER_FLAG_NO_MAPCHANGE);
	}
} 
public Action:DeletePushForce(Handle:timer, any:ent)
{
	 if (IsValidEntity(ent))
	 {
	 	decl String:classname[64];
		GetEdictClassname(ent, classname, sizeof(classname));
		if (StrEqual(classname, "point_push", false))
		{
			AcceptEntityInput(ent, "Kill"); 
		}
	 }
}
public Action:DeletePointHurt(Handle:timer, any:ent)
{
	 if (IsValidEntity(ent))
	 {
		decl String:classname[64];
		GetEdictClassname(ent, classname, sizeof(classname));
		if (StrEqual(classname, "point_hurt", false))
		{
			AcceptEntityInput(ent, "Kill"); 
		}
	 }
}
public bool:TraceRayDontHitSelfAndLive(entity, mask, any:data)
{
	if (entity == data) 
	{
		return false; 
	}
	else if (entity>0 && entity<=MaxClients)
	{
		if(IsClientInGame(entity))
		{
			return false;
		}
	}
	return true;
}
// 条件数据获取等
stock GetNearestSurvivorDist(client)
{
		new Float:PlayerPos[3], Float:TargetPos[3], Float:nearest = 0.0, Float:distance = 0.0;
	if (client > 0)
	{
		if (IsClientInGame(client) && IsPlayerAlive(client))
		{
			GetClientAbsOrigin(client, PlayerPos);
   			for (new i=1; i<=MaxClients; i++)
				{
					if (IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(i) == 2)
				{
					GetClientAbsOrigin(i, TargetPos);
								distance = GetVectorDistance(PlayerPos, TargetPos);
								if (nearest == 0.0)
					{
						nearest = distance;
					}
					else if (nearest > distance)
					{
						nearest = distance;
					}
				}
			}
		} 
		}
		return RoundFloat(distance);
}
/******************************************************
*	设置坦克类型
*******************************************************/
public SetTankType(client, type)
{
	//PrintToChatAll("玩家 %N 选择TANK类型 %d", client, type);
	tanktype[client] = type;
	new maxhealth;
	if(client > 0 && client < MaxClients && IsClientInGame(client) && IsValidEntity(client))
	{		
		if (tanktype[client] < TANK_Spawn || tanktype[client] > TANK_COUNT)
		{
			tanktype[client] = GetRandomInt(TANK_Spawn, TANK_COUNT);
			type = tanktype[client];
		}
		// 生命
		maxhealth = iTankExtraHealth[type];
		SetEntProp(client, Prop_Data, "m_iMaxHealth", maxhealth);
		SetEntProp(client, Prop_Data, "m_iHealth", maxhealth);
		// 速度
        SetEntDataFloat(client, g_iLaggedMovementO, flTankSpeed[type], true);		
		ClientCommand(client, "sm_buy");		//修复8分健康BUG的利用
		//
		//PrintToChatAll("test__03__生命 %d 速度 %f", iTankExtraHealth[type], flTankSpeed[type]);
		if (tanktype[client] == TANK_Spawn)// 菌种坦克 1
		{			
			//颜色设置
			SetEntityRenderMode(client, RenderMode:0);
			SetEntityRenderColor(client, 75, 95, 105, 255);
			// 特殊属性
			//CreateTimer(0.5, Timer_AttachSPAWN, client, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
            CreateTimer(g_fCloudHrutFreq, Timer_AttachSPAWNEx, client, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
			// 出场说明
			CPrintToChatAll("{green}菌种坦克{lightgreen}出场了!当前控制者是: {green}%N \n生命值: {lightgreen}%d  {green}移动倍数: {lightgreen}%.2f \n{olive}吸掉实验室大量毒气。自身会不停的再生瘴气，在瘴气下会让幸存者感到窒息，同时瘴气也是特感最好的掩体。", client, maxhealth, flTankSpeed[type]);
			//CPrintToChatAll("{olive}丢出的石头也会产生火焰效果!");
		}
		else if (tanktype[client] == TANK_Smasher)// 粉碎坦克 2
		{
			//颜色设置
			SetEntityRenderMode(client, RenderMode:0);
			SetEntityRenderColor(client, 70, 80, 100, 255);
			// 特殊属性
			SetEntProp(client, Prop_Send, "m_iGlowType", 3);
			new glowcolor = RGB_TO_INT(50, 50, 50);
			SetEntProp(client, Prop_Send, "m_glowColorOverride", glowcolor);
			// 出场说明
			CPrintToChatAll("{green}粉碎坦克{lightgreen}出场了!当前控制者是: {green}%N \n生命值: {lightgreen}%d  {green}移动倍数: {lightgreen}%.2f \n{olive}注入大量锇金属行动变得迟缓。但它拥有致命的铁拳。", client, maxhealth, flTankSpeed[type]);
			//CPrintToChatAll("{olive}丢出的石头也会产生火焰效果!");
		}
		else if (tanktype[client] == TANK_Warp)// 心灵坦克 3
		{
			//颜色设置
			SetEntityRenderMode(client, RenderMode:0);
			SetEntityRenderColor(client, 130, 130, 255, 255);
			// 蓄力计时
			iMoveWarpTimeFlag[client] = 1;
			iMoveWarpAbleFlag[client] = 1;
			CreateTimer(0.5, ChargeTimer, client, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);			
			// 出场说明
			CPrintToChatAll("{green}瞬移坦克{lightgreen}出场了!当前控制者是: {green}%N \n生命值: {lightgreen}%d  {green}移动倍数: {lightgreen}%.2f \n{olive}“心灵传送者” 也难逃感染的空气。感染后的它依然拥有传送的能力，可以使用鼠标中键来任意传送至幸存者身边。", client, maxhealth, flTankSpeed[type]);
			//CPrintToChatAll("{olive}丢出的石头也会产生火焰效果!");
		}
		else if (tanktype[client] == TANK_Meteor)// 陨石坦克 4
		{
			//颜色设置
			SetEntityRenderMode(client, RenderMode:0);
			SetEntityRenderColor(client, 100, 25, 25, 255);
			// 特殊属性
			CreateTimer(0.1, MeteorTankTimer, client, TIMER_FLAG_NO_MAPCHANGE);
			CreateTimer(6.0, Timer_AttachMETEOR, client, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
			// 出场说明
			CPrintToChatAll("{green}陨石坦克{lightgreen}出场了!当前控制者是: {green}%N \n生命值: {lightgreen}%d  {green}移动倍数: {lightgreen}%.2f \n{olive}召唤天上的陨石掉落在Tank身边，被陨石砸中可不是开玩笑的、", client, maxhealth, flTankSpeed[type]);
			//CPrintToChatAll("{olive}丢出的石头也会产生火焰效果!");
		}
		else if (tanktype[client] == TANK_Spitter)// 酸液坦克 5
		{
			//颜色设置
			SetEntityRenderMode(client, RenderMode:0);
			SetEntityRenderColor(client, 12, 115, 128, 255);
			// 特殊属性
			iShowSpitterIndex[client] = 0;
			CreateTimer(2.0, Timer_AttachSPIT, client, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
			// 出场说明
			CPrintToChatAll("{green}酸液坦克{lightgreen}出场了!当前控制者是: {green}%N \n生命值: {lightgreen}%d  {green}移动倍数: {lightgreen}%.2f \n{olive}被Spitter祭师过的Tank。全身充满腐朽的酸臭味，打中幸存者或丢石头会有大量的酸液携带，幸存者们要留心你的脚下了。", client, maxhealth, flTankSpeed[type]);
			//CPrintToChatAll("{olive}丢出的石头也会产生火焰效果!");
		}
		else if (tanktype[client] == TANK_Heal)// 治愈坦克 6
		{
			//颜色设置
			SetEntityRenderMode(client, RenderMode:0);
			SetEntityRenderColor(client, 100, 255, 200, 255);
			// 出场说明
			CPrintToChatAll("{green}治愈坦克{lightgreen}出场了!当前控制者是: {green}%N \n生命值: {lightgreen}%d  {green}移动倍数: {lightgreen}%.2f \n{olive}再生元素。拥有超强的再生功能，同时也可以为身边的特感同伴治疗。", client, maxhealth, flTankSpeed[type]);
			//CPrintToChatAll("{olive}丢出的石头也会产生火焰效果!");
		}
		else if (tanktype[client] == TANK_Fire)// 烈焰坦克 7
		{
			//颜色设置
			SetEntityRenderMode(client, RenderMode:0);
			SetEntityRenderColor(client, 128, 0, 0, 255);
			// 特殊属性
			CreateTimer(0.8, Timer_AttachFIRE,client, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
			// 出场说明
			CPrintToChatAll("{green}烈焰坦克{lightgreen}出场了!当前控制者是: {green}%N \n生命值: {lightgreen}%d  {green}移动倍数: {lightgreen}%.2f \n{olive}跟熔岩Tank一起从火场中进化二来。天生免疫火，它投石的地方会燃起熊熊大火。", client, maxhealth, flTankSpeed[type]);
			//CPrintToChatAll("{olive}丢出的石头也会产生火焰效果!");
		}
		else if (tanktype[client] == TANK_Ice)// 冰霜坦克 8
		{
			//颜色设置
			SetEntityRenderMode(client, RenderMode:3);
			SetEntityRenderColor(client, 0, 100, 170, 200);
			// 特殊属性
			CreateTimer(2.0, Timer_AttachICE, client, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
			// 出场说明
			CPrintToChatAll("{green}冰霜坦克{lightgreen}出场了!当前控制者是: {green}%N \n生命值: {lightgreen}%d  {green}移动倍数: {lightgreen}%.2f \n{olive}这是一只非常成功的试验品。自身已经可以产生冰霜粒子，击中幸存者会被冻住好久...好久...", client, maxhealth, flTankSpeed[type]);
			//CPrintToChatAll("{olive}丢出的石头也会产生火焰效果!");
		}
		else if (tanktype[client] == TANK_Jockey)// 猴子坦克 9
		{
			//颜色设置
			SetEntityRenderMode(client, RenderMode:0);
			SetEntityRenderColor(client, 255, 200, 0, 255);
			// 出场说明
			CPrintToChatAll("{green}猴子坦克{lightgreen}出场了!当前控制者是: {green}%N \n生命值: {lightgreen}%d  {green}移动倍数: {lightgreen}%.2f \n{olive}该坦克攻击会可以扔出猴子特感!", client, maxhealth, flTankSpeed[type]);
			//CPrintToChatAll("{olive}丢出的石头也会产生火焰效果!");
		}
		else if (tanktype[client] == TANK_Ghost)// 幽灵坦克 10
		{
			//颜色设置
			SetEntityRenderMode(client, RenderMode:3);
			SetEntityRenderColor(client, 100, 100, 100, 0);
			// 隐身术
			iMoveGhostAbleFlag[client] = 1;
			iMoveGhostBeginTimeFlag[client] = 1;
			iMoveGhostEndTimeFlag[client] = 0;
			CreateTimer(1.0, GhostTimer, client, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);  
			// 出场说明
			CPrintToChatAll("{green}幽灵坦克{lightgreen}出场了!当前控制者是: {green}%N \n生命值: {lightgreen}%d  {green}移动倍数: {lightgreen}%.2f \n{olive}在普通进化时被注入了地球一种未知元素。人类已经无法用肉眼来看到它在无形中扼杀幸存者。但这种元素非常不稳定...", client, maxhealth, flTankSpeed[type]);
			//CPrintToChatAll("{olive}丢出的石头也会产生火焰效果!");
		}
		else if (tanktype[client] == TANK_Shock)// 闪电坦克 11
		{
			//颜色设置
			SetEntityRenderMode(client, RenderMode:0);
			SetEntityRenderColor(client, 100, 165, 255, 255);
			// 特殊属性
			CreateTimer(0.8, Timer_AttachELEC, client, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
			// 出场说明
			CPrintToChatAll("{green}闪电坦克{lightgreen}出场了!当前控制者是: {green}%N \n生命值: {lightgreen}%d  {green}移动倍数: {lightgreen}%.2f \n{olive}电不怕、不怕电。被击中后大量电荷释放给幸存者让他找不到回家的路。", client, maxhealth, flTankSpeed[type]);
			//CPrintToChatAll("{olive}丢出的石头也会产生火焰效果!");
		}
		else if (tanktype[client] == TANK_Witch)// 女巫坦克 12
		{
			//颜色设置
			SetEntityRenderMode(client, RenderMode:0);
			SetEntityRenderColor(client, 255, 200, 255, 255);
			// 特殊属性
			CreateTimer(2.0, Timer_AttachBLOOD, client, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
			CreateTimer(fWitchSpawnTime, Timer_Spawn, client, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
			// 出场说明
			CPrintToChatAll("{green}女巫坦克{lightgreen}出场了!当前控制者是: {green}%N \n生命值: {lightgreen}%d  {green}移动倍数: {lightgreen}%.2f \n{olive}意念大师Alan被抓后非常想念妻子直至被进化后也是如此...。被它触碰过的小丧尸都有机率变成他的妻子。", client, maxhealth, flTankSpeed[type]);
			//CPrintToChatAll("{olive}丢出的石头也会产生火焰效果!");
		}
		else if (tanktype[client] == TANK_Shield)// 护盾坦克 13
		{
			//颜色设置
			SetEntityRenderMode(client, RenderMode:0);
			SetEntityRenderColor(client, 135, 205, 255, 255);
			// 特殊属性
			ActivateShield(client);
			bShieldDemageFlag[client] = false;
			CPrintToChatAll("护盾生成");
			// 出场说明
			CPrintToChatAll("{green}护盾坦克{lightgreen}出场了!当前控制者是: {green}%N \n生命值: {lightgreen}%d  {green}移动倍数: {lightgreen}%.2f \n{olive}不只从哪个实验室改造出来的产物，有一层刀枪不入的护盾。唯一弱点是怕瓦斯罐爆炸后大面积冲击力会让护盾暂时失效。 ", client, maxhealth, flTankSpeed[type]);
			//CPrintToChatAll("{olive}丢出的石头也会产生火焰效果!");
		}
		else if (tanktype[client] == TANK_Cobalt)// 神行坦克 14
		{
			//颜色设置
			SetEntityRenderMode(client, RenderMode:0);
			SetEntityRenderColor(client, 0, 105, 255, 255);
			// 蓄力计时
			iMoveCobaltAbleFlag[client] = 1;
			iMoveCobaltBeginTimeFlag[client] = 1;
			iMoveCobaltEndTimeFlag[client] = 0;	
            // 效果
			CreateTimer(1.0, CobaltTimer, client, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);  
			// 出场说明
			CPrintToChatAll("{green}神行坦克{lightgreen}出场了!当前控制者是: {green}%N \n生命值: {lightgreen}%d  {green}移动倍数: {lightgreen}%.2f \n{olive}改造出几乎完美的双腿。拥有不敢想像的移动速度。", client, maxhealth, flTankSpeed[type]);
			//CPrintToChatAll("{olive}丢出的石头也会产生火焰效果!");
		}
		else if (tanktype[client] == TANK_Jumper)// 跳跃坦克 15
		{
			//颜色设置
			SetEntityRenderMode(client, RenderMode:0);
			SetEntityRenderColor(client, 200, 255, 0, 255);
			// 特殊属性
			bJumperPressDelayp[client] = false;
			CreateTimer(0.1, JumperTankTimer, client, TIMER_FLAG_NO_MAPCHANGE);
			//CreateTimer(fJumperJumpDelay, JumpTimer, client, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
			// 出场说明
			CPrintToChatAll("{green}跳跃坦克{lightgreen}出场了!当前控制者是: {green}%N \n生命值: {lightgreen}%d  {green}移动倍数: {lightgreen}%.2f \n{olive}扔到废车场失败的测试品。不自主的乱跳，如果不小心被它踩到头或肩，可不是开玩笑的。 ", client, maxhealth, flTankSpeed[type]);
			//CPrintToChatAll("{olive}丢出的石头也会产生火焰效果!");
		}
		else if (tanktype[client] == TANK_Gravity)// 磁力坦克 16
		{
			//颜色设置
			SetEntityRenderMode(client, RenderMode:0);
			SetEntityRenderColor(client, 33, 34, 35, 255);
			// 特殊属性
            SetEntityGravity(client, 0.5);
			//CreateTimer(0.1, GravityTankTimer, client, TIMER_FLAG_NO_MAPCHANGE);
            CreateTimer(g_fGravityFreqTimes, GravityTankTimerEx, client, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
			// 出场说明
			CPrintToChatAll("{green}磁力坦克{lightgreen}出场了!当前控制者是: {green}%N \n生命值: {lightgreen}%d  {green}移动倍数: {lightgreen}%.2f \n{olive}“漫威漫画” 一直是美国人的喜爱。这些疯子什么都敢弄，仿制了一个比钢铁侠还厉害的万有引力反应堆。", client, maxhealth, flTankSpeed[type]);
			//CPrintToChatAll("{olive}丢出的石头也会产生火焰效果!");
		}
		else if (tanktype[client] == TANK_Boomer)// 胆汁坦克 17
		{
			//颜色设置
			SetEntityRenderMode(client, RenderMode:0);
			SetEntityRenderColor(client, 255, 248, 100, 255);
			// 特殊属性
			iShowBoomerIndex[client] = 0;
			// 出场说明
			CPrintToChatAll("{green}胆汁坦克{lightgreen}出场了!当前控制者是: {green}%N \n生命值: {lightgreen}%d  {green}移动倍数: {lightgreen}%.2f \n{olive}是酸液Tank前期产物。拥有无限的Boomer的呕液，击中幸存者会让他满脸疮痍。", client, maxhealth, flTankSpeed[type]);
			//CPrintToChatAll("{olive}丢出的石头也会产生火焰效果!");
		}
		else if (tanktype[client] == TANK_RongYan)// 熔岩坦克 18
		{
			//颜色设置
			SetEntityRenderMode(client, RenderMode:0);
			DispatchKeyValue(client, "rendercolor", "255 80 80");
			CPrintToChatAll("{green}熔岩坦克{lightgreen}出场了!当前控制者是: {green}%N \n生命值: {lightgreen}%d  {green}移动倍数: {lightgreen}%.2f \n{olive}跟烈焰Tank一起从火场中进化二来。拥有一身致烫熔岩皮肤，击中幸存者会穿心的烫伤，同时熔岩皮肤还会反伤近战伤害。", client, maxhealth, flTankSpeed[type]);
			CPrintToChatAll("{olive}丢出的石头也会产生火焰效果!");
		}
		else if (tanktype[client] == TANK_ZhongLi)// 重力坦克 19
		{
			//颜色设置
			SetEntityRenderMode(client, RenderMode:0);
			DispatchKeyValue(client, "rendercolor", "80 255 80");
			CPrintToChatAll("{green}重力坦克{lightgreen}出场了!当前控制者是: {green}%N \n生命值: {lightgreen}%d  {green}移动倍数: {lightgreen}%.2f \n{olive}可以自由掌握万有引起。击中幸存者后短时间会失去地心引力，当恢复引力后它已经远离地面数米了。", client, maxhealth, flTankSpeed[type]);
		}
		else if (tanktype[client] == TANK_KongJu)// 恐惧坦克 20
		{
			 //颜色设置
			SetEntityRenderMode(client, RenderMode:0);
			DispatchKeyValue(client, "rendercolor", "90 90 90");
			CPrintToChatAll("{green}恐惧坦克{lightgreen}出场了!当前控制者是: {green}%N \n生命值: {lightgreen}%d  {green}移动倍数: {lightgreen}%.2f \n{olive}能读懂人类内心恐惧的一面信息并迅速的转化成外部能力释放给幸存者，攻击会造成他短时间致盲状态,请小心对待！", client, maxhealth, flTankSpeed[type]);
		}
		else if (tanktype[client] == TANK_DiZhen)// 地震坦克 21
		{
			//颜色设置
			SetEntityRenderMode(client, RenderMode:0);
			DispatchKeyValue(client, "rendercolor", "255 255 80");
			CPrintToChatAll("{green}地震坦克{lightgreen}出场了!当前控制者是: {green}%N \n生命值: {lightgreen}%d  {green}移动倍数: {lightgreen}%.2f \n{olive}见到幸存者躺地会迅速的跑过去举双手用力捶打他。这种捶打是非常有力的，范围幸存者可以明显感觉到这种Tank的威慑力。", client, maxhealth, flTankSpeed[type]);
			CPrintToChatAll("{olive}丢出的石头也会产生爆炸效果!");
		}
		else if (tanktype[client] == TANK_YouJi)// 游击坦克 22
		{
			//重力设置
			SetEntityGravity(client, 0.2);
			//颜色设置
			SetEntityRenderMode(client, RenderMode:0);
			DispatchKeyValue(client, "rendercolor", "255 20 255");
			CPrintToChatAll("{green}游击坦克{lightgreen}出场了!当前控制者是: {green}%N \n生命值: {lightgreen}%d  {green}移动倍数: {lightgreen}%.2f \n{olive}改造出几乎完美的双腿。拥有不敢想像的移动速度。", client, maxhealth, flTankSpeed[type]);
		}
		else if (tanktype[client] == TANK_Double)// 分身坦克 23
		{
			//颜色设置
			//SetEntityRenderMode(client, RenderMode:0);
			//DispatchKeyValue(client, "rendercolor", "255 20 255");
			// 特殊属性
			CreateTimer(0.1, DoubleTankTimer, maxhealth, TIMER_FLAG_NO_MAPCHANGE);
			CPrintToChatAll("{green}分身坦克{lightgreen}出场了!当前控制者是: {green}%N \n生命值: {lightgreen}%d  {green}移动倍数: {lightgreen}%.2f \n{olive}小型寄生体。被激怒后会快速复制自身，产生多个完整复制体。", client, maxhealth, flTankSpeed[type]);
		}
		else if (tanktype[client] == TANK_Adrenal)// 暴走坦克 24
		{
			//颜色设置
			//SetEntityRenderMode(client, RenderMode:0);
			//DispatchKeyValue(client, "rendercolor", "255 20 255");
			// 特殊属性
			//CreateTimer(0.1, AdrenalTankTimer, client, TIMER_FLAG_NO_MAPCHANGE);
			CPrintToChatAll("{green}暴走坦克{lightgreen}出场了!当前控制者是: {green}%N \n生命值: {lightgreen}%d  {green}移动倍数: {lightgreen}%.2f \n{olive}疯狂暴走的它让所有感染者拥有没有技能冷却的攻击能力。", client, maxhealth, flTankSpeed[type]);
		}
		else if (tanktype[client] == TANK_RenZhe)// 忍者坦克 25
		{
			//颜色设置
			SetEntityRenderMode(client, RenderMode:0);
			DispatchKeyValue(client, "rendercolor", "0 0 0, 255");
			// 特殊属性
            bRenZhePressDelayp[client] = false;
			//CreateTimer(0.1, AdrenalTankTimer, client, TIMER_FLAG_NO_MAPCHANGE);
			CPrintToChatAll("{green}忍者坦克{lightgreen}出场了!当前控制者是: {green}%N \n生命值: {lightgreen}%d  {green}移动倍数: {lightgreen}%.2f \n{olive}继承日本数千年的忍道。按鼠标中键 能够无形的出现在幸存者身后给予幸存者致命一击，防不胜防。", client, maxhealth, flTankSpeed[type]);
		}
		// 投石速度
		ResetInfectedAbility(client, flTankThrow[type]);
		//速度设置检测
		CreateTimer(1.0, tankspeedcheck, client);
	}
}

stock DealDamagePlayer(target, attacker, dmgtype, dmg)
{
	if (target > 0 && target <= MaxClients)
	{
		if (IsClientInGame(target) && IsPlayerAlive(target))
		{
   	 		decl String:damage[16];
				IntToString(dmg, damage, 16);
   	 		decl String:type[16];
				IntToString(dmgtype, type, 16);
			new pointHurt = CreateEntityByName("point_hurt");
			if (pointHurt)
			{
				DispatchKeyValue(target, "targetname", "hurtme");
				DispatchKeyValue(pointHurt, "Damage", damage);
				DispatchKeyValue(pointHurt, "DamageTarget", "hurtme");
				DispatchKeyValue(pointHurt, "DamageType", type);
				DispatchSpawn(pointHurt);
				AcceptEntityInput(pointHurt, "Hurt", attacker);
				AcceptEntityInput(pointHurt, "Kill");
				DispatchKeyValue(target, "targetname", "donthurtme");
			}
		}
	}
}
stock DealDamageEntity(target, attacker, dmgtype, dmg)
{
	if (target > 32)
	{
		if (IsValidEntity(target))
		{
   	 		decl String:damage[16];
				IntToString(dmg, damage, 16);
   	 		decl String:type[16];
				IntToString(dmgtype, type, 16);
			new pointHurt = CreateEntityByName("point_hurt");
			if (pointHurt)
			{
				DispatchKeyValue(target, "targetname", "hurtme");
				DispatchKeyValue(pointHurt, "Damage", damage);
				DispatchKeyValue(pointHurt, "DamageTarget", "hurtme");
				DispatchKeyValue(pointHurt, "DamageType", type);
				DispatchSpawn(pointHurt);
				AcceptEntityInput(pointHurt, "Hurt", attacker);
				AcceptEntityInput(pointHurt, "Kill");
				DispatchKeyValue(target, "targetname", "donthurtme");
			}
		}
	}
}
stock ForceWeaponDrop(client)
{
	if (GetPlayerWeaponSlot(client, 1) > 0)
	{
		new weapon = GetPlayerWeaponSlot(client, 1);
		SDKHooks_DropWeapon(client, weapon, NULL_VECTOR, NULL_VECTOR);
	}
}
stock ResetInfectedAbility(client, Float:time)
{
	if (client > 0)
	{
		if (IsClientInGame(client) && IsPlayerAlive(client) && GetClientTeam(client) == 3)
		{
			new ability = GetEntPropEnt(client, Prop_Send, "m_customAbility");
			if (ability > 0)
			{
				SetEntPropFloat(ability, Prop_Send, "m_duration", time);
				SetEntPropFloat(ability, Prop_Send, "m_timestamp", GetGameTime() + time);
			}
		}
	}
}
stock Pick()
{
		new count, clients[MaxClients];
		for (new i=1; i<= MaxClients; i++)
		{
			if (IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(i) == 2)
					clients[count++] = i; 
		}
		return clients[GetRandomInt(0,count-1)];
}
stock bool:IsSpecialInfected(client)
{
	if (IsValidPlayer(client, true, false) && GetClientTeam(client) == 3)
	{
		if(GetEntProp(client, Prop_Send, "m_zombieClass") == 8)
		{
			return false;
		}
		else
		{
			return true;
		}
	}
	return false;
}
// 心灵传送
stock TeleportTank(client)
{
	new target = Pick();
	if (target && bMoveWarpFlag[client])
	{
		new Float:Origin[3], Float:Angles[3];
		GetClientAbsOrigin(target, Origin);
		GetClientAbsAngles(target, Angles);
		AttachParticle(client, PARTICLE_ELEC, 2.8, 0.0);
		AttachParticle(client, PARTICLE_ELEC, 0.5, 0.0);
		TeleportEntity(client, Origin, Angles, NULL_VECTOR);
		//
		bMoveWarpFlag[client] = false;
		iMoveWarpTimeFlag[client] = 1;
	}	
}
public Action:ChargeTimer(Handle:timer, any:client)
{
	if(!iMoveWarpAbleFlag[client])
	{
		return Plugin_Stop;
	}
	if(iMoveWarpTimeFlag[client] <= 0)
	{// 强制瞬移
		bMoveWarpFlag[client] = true;
		TeleportTank(client);
	}
	else
	{
		if(iMoveWarpTimeFlag[client] >= iMoveWarpTimes || bMoveWarpFlag[client])
		{// 完成
			new i;
			bMoveWarpFlag[client] = true;
			iMoveWarpTimeFlag[client]--;
		
			new String:ChargeBar[iMoveWarpTimes];
			for(i=0; i < iMoveWarpTimes; i++)
			{
				ChargeBar[i] = '#';
			}
			for(i=iMoveWarpTimeFlag[client]-1; i < iMoveWarpTimes; i++)
			{
				ChargeBar[i] = '=';
			}
			new pro = 5*iMoveWarpTimeFlag[client];
			PrintHintText(client, "<< 心 灵 传 送 能 量 释 放 >>\n0 %s %d", ChargeBar, pro);
		}
		else if(iMoveWarpTimeFlag[client] > 0 && iMoveWarpTimeFlag[client] < iMoveWarpTimes)
		{
			new i;
			iMoveWarpTimeFlag[client]++;
			new String:ChargeBar[iMoveWarpTimes];
			for(i=0; i < iMoveWarpTimes; i++)
			{
				ChargeBar[i] = '=';
			}
			for(i=0; i < iMoveWarpTimeFlag[client]; i++)
			{
				ChargeBar[i] = '#';
			}
			new pro = 5*iMoveWarpTimeFlag[client];
			PrintHintText(client, "<< 心 灵 传 送 能 量 堆 积 >>\n0 %s %d", ChargeBar, pro);
		}
		else
		{
		}
	}
	return Plugin_Continue;   
}
// 神行术
public Action:CobaltTimer(Handle:timer, any:client)
{
	if(!iMoveCobaltAbleFlag[client])
	{
		return Plugin_Stop;
	}
    if(iMoveCobaltEndTimeFlag[client] == 0)
    {
        //CPrintToChatAll("More__ %d", iMoveCobaltBeginTimeFlag[client]);
        if(iMoveCobaltBeginTimeFlag[client] > 0 && iMoveCobaltBeginTimeFlag[client] < iMoveCobaltBeginTimes)
        {// 神行中		
            if(iMoveCobaltBeginTimeFlag[client] == 1)
            {
                //CPrintToChatAll("More %f", flCobaltSpecialSpeed);
                CreateTimer(0.3, BlurEffect, client, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
                // 速度
                SetEntDataFloat(client, g_iLaggedMovementO, flCobaltSpecialSpeed, true);
            }		
        
            new i;
            new String:ChargeBar[iMoveCobaltBeginTimes];
            for(i=0; i < iMoveCobaltBeginTimes; i++)
            {
			ChargeBar[i] = '=';
            }
            for(i=0; i < iMoveCobaltBeginTimeFlag[client]; i++)
            {
                ChargeBar[i] = '#';
            }
            new pro = 2*iMoveCobaltBeginTimeFlag[client];
            PrintHintText(client, "<< 神 行 技 能 进 行 中 >>\n0 %s %d", ChargeBar, pro);
            iMoveCobaltBeginTimeFlag[client] += 1;	
        }
        else
        {// 神行结束
            iMoveCobaltBeginTimeFlag[client] = 0;		
            iMoveCobaltEndTimeFlag[client] += 1;
        }
        //CPrintToChatAll("More00 %d", iMoveCobaltBeginTimeFlag[client]);
    }
    
	//
    if(iMoveCobaltBeginTimeFlag[client] == 0)
	{
        if(iMoveCobaltEndTimeFlag[client] > 0 && iMoveCobaltEndTimeFlag[client] < iMoveCobaltEndTimes)
        {// CD中
            if(iMoveCobaltEndTimeFlag[client] == 1)
            {
                //CPrintToChatAll("CD %f", flTankSpeed[client]);
                // 速度
                SetEntDataFloat(client, g_iLaggedMovementO, flTankSpeed[client], true);
            }
		
            new i, j, index;
            new String:ChargeBar[iMoveCobaltBeginTimes];
            for(i=0; i < iMoveCobaltBeginTimes; i++)
            {
                ChargeBar[i] = '#';
            }
            index = 10 * iMoveCobaltEndTimeFlag[client];
            for(i=0; i < index; i++)
            {
                ChargeBar[i] = '=';
            }
            new pro = 20*iMoveCobaltEndTimeFlag[client];
            PrintHintText(client, "<< 神 行 技 能 冷 却 中 >>\n0 %s %d", ChargeBar, pro);
            iMoveCobaltEndTimeFlag[client] += 1;
        }
        else
        {// CD结束
            iMoveCobaltEndTimeFlag[client] = 0;		
            iMoveCobaltBeginTimeFlag[client] += 1;
        }
    }
    //CPrintToChatAll("More01 %d", iMoveCobaltBeginTimeFlag[client]);
	return Plugin_Continue;   
}
// 隐身术
public Action:GhostTimer(Handle:timer, any:client)
{
	if(!iMoveGhostAbleFlag[client])
	{
		return Plugin_Stop;
	}
    if(iMoveGhostEndTimeFlag[client] == 0)
    {
        //CPrintToChatAll("More__ %d", iMoveGhostBeginTimeFlag[client]);
        if(iMoveGhostBeginTimeFlag[client] > 0 && iMoveGhostBeginTimeFlag[client] < iMoveGhostBeginTimes)
        {// 隐身中		
            if(iMoveGhostBeginTimeFlag[client] == 1)
            {
                //CPrintToChatAll("隐身modle");
                SetEntityRenderMode(client, RenderMode:3);
                SetEntityRenderColor(client, 100, 100, 100, 0);
            }		
            // 显示进度条
            new i;
            new String:ChargeBar[iMoveGhostBeginTimes];
            for(i=0; i < iMoveGhostBeginTimes; i++)
            {
                ChargeBar[i] = '=';
            }
            for(i=0; i < iMoveGhostBeginTimeFlag[client]; i++)
            {
                ChargeBar[i] = '#';
            }
            new pro = 2*iMoveGhostBeginTimeFlag[client];
            PrintHintText(client, "<< 隐 身 技 能 进 行 中 >>\n0 %s %d", ChargeBar, pro);
            iMoveGhostBeginTimeFlag[client] += 1;   
        }
        else
        {// 神行结束
            iMoveGhostBeginTimeFlag[client] = 0;
            iMoveGhostEndTimeFlag[client] += 1;
        }
    }
    
    //
    if(iMoveGhostBeginTimeFlag[client] == 0)
    {
        if(iMoveGhostEndTimeFlag[client] > 0 && iMoveGhostEndTimeFlag[client] < iMoveGhostEndTimes)
        {// 现身中
            if(iMoveGhostEndTimeFlag[client] == 1)
            {
                //CPrintToChatAll("去除隐身modle_________________");
                SetEntityRenderMode(client, RenderMode:0);
                SetEntityRenderColor(client, 100, 100, 100, 255);
            }		
            new i, j, index;
            new String:ChargeBar[iMoveGhostBeginTimes];
            for(i=0; i < iMoveGhostBeginTimes; i++)
            {
                ChargeBar[i] = '#';
            }
            index = 10 * iMoveGhostEndTimeFlag[client];
            for(i=0; i < index; i++)
            {			
                ChargeBar[i] = '=';
            }
            new pro = 20 * iMoveGhostEndTimeFlag[client];
            PrintHintText(client, "<< 隐 身 技 能 冷 却 中 >>\n0 %s %d", ChargeBar, pro);
            iMoveGhostEndTimeFlag[client] += 1;
        }
        else
        {// CD结束
            iMoveGhostEndTimeFlag[client] = 0;		
            iMoveGhostBeginTimeFlag[client] += 1;
        } 
    }	
	return Plugin_Continue;      
}
stock CountWitches()
{
	new count;
	new entity = -1;
	while ((entity = FindEntityByClassname(entity, "witch")) != INVALID_ENT_REFERENCE)
	{
		count++;
	}
	return count;
}
stock SpawnWitch(client)
{
	new count = 0;
	new entity = -1;
	while ((entity = FindEntityByClassname(entity, "infected")) != INVALID_ENT_REFERENCE)
	{
		if (count < 1 && CountWitches() < iWitchMaxWitches)
		{
			decl Float:TankPos[3], Float:InfectedPos[3], Float:InfectedAng[3];
						GetClientAbsOrigin(client, TankPos);
			GetEntPropVector(entity, Prop_Send, "m_vecOrigin", InfectedPos);
			GetEntPropVector(entity, Prop_Send, "m_angRotation", InfectedAng);
			new Float:distance = GetVectorDistance(InfectedPos, TankPos);
			if (distance < fWitchSpawnDistance)
			{
				AcceptEntityInput(entity, "Kill");
				new witch = CreateEntityByName("witch");
				DispatchSpawn(witch);
				ActivateEntity(witch);
				TeleportEntity(witch, InfectedPos, InfectedAng, NULL_VECTOR);
				SetEntProp(witch, Prop_Send, "m_hOwnerEntity", 255200255);
				count++;
			}
		}
	}
}
stock HealTank(client)
{
	if(IsValidPlayer(client, false, false))
	{
		for (new i=1; i<=MaxClients; i++)
		{			
			if (IsSpecialInfected(i))
			{// 特感
				decl Float:TankPos[3], Float:InfectedPos[3];
				GetClientAbsOrigin(client, TankPos);
				GetClientAbsOrigin(i, InfectedPos);
				new Float:distance = GetVectorDistance(TankPos, InfectedPos);
				//PrintToChatAll("回血 %N__%d", i, distance);
				if (distance < iHealTankDistance)
				{
					new health = GetEntProp(i, Prop_Data, "m_iHealth");
					new maxhealth = g_iPlayerMaxHealth[i];
					new healValue = RoundToZero(maxhealth * fHealHealthSpecials);
					//PrintToChatAll("特感%N治愈：%d, max__%d__value _ %d", i, health, maxhealth, healValue);
					if (health <= (maxhealth - healValue))
					{
						SetEntProp(i, Prop_Data, "m_iHealth", health + healValue);
					}
					else
					{
						SetEntProp(i, Prop_Data, "m_iHealth", maxhealth);
					}
					// 颜色效果添加
					new glowcolor = RGB_TO_INT(0, 220, 0);
					SetEntProp(i, Prop_Send, "m_glowColorOverride", glowcolor);
					SetEntProp(i, Prop_Send, "m_iGlowType", 3);
					SetEntProp(i, Prop_Send, "m_bFlashing", 1);
				}
				else
				{// 颜色效果去除
					SetEntProp(i, Prop_Send, "m_glowColorOverride", 0);
					SetEntProp(i, Prop_Send, "m_iGlowType", 0);
					SetEntProp(i, Prop_Send, "m_bFlashing", 0);
				}
			}
			else if (IsTank(i))
			{
				decl Float:TankPos[3], Float:InfectedPos[3];
				GetClientAbsOrigin(client, TankPos);
				GetClientAbsOrigin(i, InfectedPos);
				new Float:distance = GetVectorDistance(TankPos, InfectedPos);
				if (distance < iHealTankDistance)
				{
					new health = GetEntProp(i, Prop_Data, "m_iHealth");
					new maxhealth = GetEntProp(i, Prop_Data, "m_iMaxHealth");
					new healValue = RoundToZero(maxhealth * fHealHealthTanks);
					//PrintToChatAll("TANK%N治愈：%d, max__%d__value _ %d", i, health, maxhealth, healValue);
					if (health <= (maxhealth - healValue))
					{
						SetEntProp(i, Prop_Data, "m_iHealth", health + healValue);
					}
					else
					{
						SetEntProp(i, Prop_Data, "m_iHealth", maxhealth);
					}
					// 颜色效果添加
					new glowcolor = RGB_TO_INT(0, 255, 0);
					SetEntProp(i, Prop_Send, "m_glowColorOverride", glowcolor);
					SetEntProp(i, Prop_Send, "m_iGlowType", 3);
					SetEntProp(i, Prop_Send, "m_bFlashing", 1);
				}
				else
				{// 颜色效果去除
					SetEntProp(i, Prop_Send, "m_glowColorOverride", 0);
					SetEntProp(i, Prop_Send, "m_iGlowType", 0);
					SetEntProp(i, Prop_Send, "m_bFlashing", 0);
				}
				
			}
		}
	}	
}
stock InfectedCloak(client)
{
	for (new i=1; i<=MaxClients; i++)
	{
		if (IsSpecialInfected(i))
		{
			decl Float:TankPos[3], Float:InfectedPos[3];
						GetClientAbsOrigin(client, TankPos);
						GetClientAbsOrigin(i, InfectedPos);
					   	new Float:distance = GetVectorDistance(TankPos, InfectedPos);
						if (distance < iGhostRadiiValue)
			{
				SetEntityRenderMode(i, RenderMode:3);
	  	 		SetEntityRenderColor(i, 255, 255, 255, 0);
			}
			else
			{
				SetEntityRenderMode(i, RenderMode:3);
	  	 		SetEntityRenderColor(i, 255, 255, 255, 255);
			}
		}
	}
}
stock CountSurvRange(client)
{
	new count = 0;
	for (new i=1; i<=MaxClients; i++)
	{
		if (IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(i) == 2)
		{
			decl Float:TankPos[3], Float:PlayerPos[3];
						GetClientAbsOrigin(client, TankPos);
						GetClientAbsOrigin(i, PlayerPos);
					   	new Float:distance = GetVectorDistance(TankPos, PlayerPos);
						if (distance > 120)
			{
				count++;
			}
		}
	}
	return count;
}
public Action:CreateParticle(target, String:particlename[], Float:time, Float:origin)
{
	if (target > 0)
	{
   		new particle = CreateEntityByName("info_particle_system");
			if (IsValidEntity(particle))
			{
				new Float:pos[3];
			GetEntPropVector(target, Prop_Send, "m_vecOrigin", pos);
			pos[2] += origin;
			TeleportEntity(particle, pos, NULL_VECTOR, NULL_VECTOR);
			DispatchKeyValue(particle, "effect_name", particlename);
			DispatchKeyValue(particle, "targetname", "particle");
			DispatchSpawn(particle);
			ActivateEntity(particle);
			AcceptEntityInput(particle, "start");
			CreateTimer(time, DeleteParticles, particle, TIMER_FLAG_NO_MAPCHANGE);
		}
		}
}
stock ExecTankDeath(client)
{
	TankAbility[client] = 0;

	new entity = -1;
	while ((entity = FindEntityByClassname(entity, "prop_dynamic")) != INVALID_ENT_REFERENCE)
	{
		decl String:model[128];
				GetEntPropString(entity, Prop_Data, "m_ModelName", model, sizeof(model));
		if (StrEqual(model, "models/props_debris/concrete_chunk01a.mdl"))
		{
			new owner = GetEntProp(entity, Prop_Send, "m_hOwnerEntity");
			if (owner == client)
			{
				AcceptEntityInput(entity, "Kill");
			}
		}
		else if (StrEqual(model, "models/props_vehicles/tire001c_car.mdl"))
		{
			new owner = GetEntProp(entity, Prop_Send, "m_hOwnerEntity");
			if (owner == client)
			{
				AcceptEntityInput(entity, "Kill");
			}
		}
		else if (StrEqual(model, "models/props_unique/airport/atlas_break_ball.mdl"))
		{
			new owner = GetEntProp(entity, Prop_Send, "m_hOwnerEntity");
			if (owner == client)
			{
				AcceptEntityInput(entity, "Kill");
			}
		}
	}
	while ((entity = FindEntityByClassname(entity, "beam_spotlight")) != INVALID_ENT_REFERENCE)
	{
		new owner = GetEntProp(entity, Prop_Send, "m_hOwnerEntity");
		if (owner == client)
		{
			AcceptEntityInput(entity, "Kill");
		}
	}
	while ((entity = FindEntityByClassname(entity, "point_push")) != INVALID_ENT_REFERENCE)
	{
		new owner = GetEntProp(entity, Prop_Send, "m_glowColorOverride");
		if (owner == client)
		{
			AcceptEntityInput(entity, "Kill");
		}
	}
	// 护盾
	if (IsTank(client) && tanktype[client] == TANK_Shield)
	{
		new entity = -1;
		while ((entity = FindEntityByClassname(entity, "prop_dynamic")) != INVALID_ENT_REFERENCE)
		{
			decl String:model[128];
			GetEntPropString(entity, Prop_Data, "m_ModelName", model, sizeof(model));
			if (StrEqual(model, "models/props_unique/airport/atlas_break_ball.mdl"))
			{
				new owner = GetEntProp(entity, Prop_Send, "m_hOwnerEntity");
				if (owner == client)
				{
					AcceptEntityInput(entity, "Kill");
				}
			}
		}
		//SetEntProp(client, Prop_Data, "m_takedamage", 2, 1);
		CreateTimer(flShieldShieldsDownInterval, ActivateShieldTimer, client, TIMER_FLAG_NO_MAPCHANGE);
		bShieldDemageFlag[client] = true;
	}
}
//=============================
// TANK CONTROLLER
//=============================
public TankController()
{
	CountTanks();
	if (iNumTanks > 0)
	{
		for (new i=1; i<=MaxClients; i++)
		{
			if (IsTank(i) && !bIsDoubleTankSpawn[i])
			{
				new tank_type = tanktype[i];

						switch(tank_type)
						{
							case TANK_Spawn: // 菌种，舌头烟雾效果
							{
								
							}
							case TANK_Warp: // 瞬移
							{
								//TeleportTank(i);
							}
							case TANK_Meteor:   // 陨石
							{
								if (TankAbility[i] == 0)
								{
									StartMeteorFall(i);	
								}
							}
							case TANK_Heal: // 治愈
							{
								HealTank(i);
							}
							case TANK_Fire: // 烈焰
							{
								IgniteEntity(i, 1.0);
							}
							case TANK_Ghost:	// 幽灵
							{
								InfectedCloak(i);
							}
							case TANK_Witch: // 女巫
							{
								//SpawnWitch(i);
							}
							case TANK_Shield:   // 护盾
							{
								if (bShieldDemageFlag[i])
								{
									new glowcolor = RGB_TO_INT(120, 90, 150);
									SetEntProp(i, Prop_Send, "m_iGlowType", 2);
									SetEntProp(i, Prop_Send, "m_bFlashing", 2);
									SetEntProp(i, Prop_Send, "m_glowColorOverride", glowcolor);
								}
								else
								{
									SetEntProp(i, Prop_Send, "m_iGlowType", 0);
									SetEntProp(i, Prop_Send, "m_bFlashing", 0);
									SetEntProp(i, Prop_Send, "m_glowColorOverride", 0);
								}
							}
							case TANK_Gravity:  // 磁力
							{
								//SetEntityGravity(i, 0.5);
							}
						}
						if (bTankFireImmunity[tank_type])
						{
							//if (IsPlayerBurning(i))
							//{
							//	ExtinguishEntity(i);
							//	SetEntPropFloat(i, Prop_Send, "m_burnPercent", 1.0);
							//}
						}
			}
            // 受到闪电tank攻击
            if(g_iShockHurtFlag[i])
            {
                if(g_iShockHurtTimes[i] >= g_iSkillViewTime)
                {
                    g_iShockHurtFlag[i] = 0;
                    g_iShockHurtTimes[i] = 0;
                    // 黑屏恢复
                    RemoveSkillViewEx(i);
                }
                g_iShockHurtTimes[i]++;
            }
		}
	}
}
//=============================
// COMMANDS
//=============================

//
//=============================
// Speed on Ground and in Water
//=============================
SpeedRebuild(client)
{
	new Float:value;
	if (PlayerSpeed[client] > 0)
	{
		value = flShockStunMovement;
	}
	else
	{
		value = 1.0;
	}
	//SetEntPropFloat(client, Prop_Data, "m_flLaggedMovementValue", value);
	// 速度
	//SetEntDataFloat(client, g_iLaggedMovementO, value, true);
}
//=============================
// GAMEFRAME
//=============================
public OnGameFrame()
{
	if (!IsServerProcessing()) return;

	if (bSuperTanksEnabled)
	{
		iFrame++;
		if (iFrame >= 3)
		{
			for (new i=1; i<=MaxClients; i++)
			{
				if (IsClientInGame(i) && IsPlayerAlive(i) && GetClientTeam(i) == 2)
				{
					SpeedRebuild(i);
				}
			}
			iFrame = 0;
		}
	}
}
//=============================
// TIMER 0.1
//=============================
public Action:TimerUpdate01(Handle:timer)
{
	if (!IsServerProcessing()) return Plugin_Continue;

	if (bSuperTanksEnabled && bDisplayHealthCvar)
	{
		for (new i=1; i<=MaxClients; i++)
		{
			if (IsClientInGame(i) && GetClientTeam(i) == 2)
			{
				if (!IsFakeClient(i))
				{
					new entity = GetClientAimTarget(i, false);
					if (IsValidEntity(entity))
					{
						new String:classname[32];
						GetEdictClassname(entity, classname, sizeof(classname));
						if (StrEqual(classname, "player", false))
						{
							if (entity > 0)
							{
								if (IsTank(entity))
								{
									new health = GetClientHealth(entity);
									PrintHintText(i, "%N (%d HP)", entity, health);
								}
							}
						}
					}
				}
			}
		}
	}
	return Plugin_Continue;
}
//=============================
// TIMER 1.0
//=============================
//以下  屏蔽插件解除32人问题，我也不知道为什么作者为什么会限制32人

public Action:TimerUpdate1(Handle:timer)
{
	if (!IsServerProcessing()) return Plugin_Continue;

	if (bSuperTanksEnabled)
	{
		
		TankController();		
		//SetConVarInt(FindConVar("z_max_player_zombies"), 32);
		for (new i=1; i<=MaxClients; i++)
		{
			if (IsClientInGame(i) && 0)
			{
				if (GetClientTeam(i) == 2)
				{
					if (PlayerSpeed[i] > 0)
					{
						PlayerSpeed[i] -= 1;
					}
				}
				else if (GetClientTeam(i) == 3)
				{
					if (IsFakeClient(i))
					{
						new zombie = GetEntData(i, FindSendPropInfo("CTerrorPlayer", "m_zombieClass"));
						if (zombie == 8)
						{
							CreateTimer(3.0, TankLifeCheck, i, TIMER_FLAG_NO_MAPCHANGE);
						}
					}
				}
			}
		}
	}

	return Plugin_Continue;
}

// 菌种毒雾伤害
static CreateGasCloud(client, Float:g_pos[3])
{
    #if DEBUG
    PrintToChatAll("Action GasCloud running");
    #endif
    
    new Float:targettime = GetEngineTime() + GetConVarFloat(CloudDuration);
    
    new Handle:data = CreateDataPack();
    WritePackCell(data, client);
    WritePackFloat(data, g_pos[0]);
    WritePackFloat(data, g_pos[1]);
    WritePackFloat(data, g_pos[2]);
    WritePackFloat(data, targettime);
    
    CreateTimer(2.0, Point_Hurt, data, TIMER_REPEAT);
}



public Action:Point_Hurt(Handle:timer, Handle:hurt)
{
    ResetPack(hurt);
    new client = ReadPackCell(hurt);
    decl Float:g_pos[3];
    g_pos[0] = ReadPackFloat(hurt);
    g_pos[1] = ReadPackFloat(hurt);
    g_pos[2] = ReadPackFloat(hurt);
    new Float:targettime = ReadPackFloat(hurt);
    
    if (targettime - GetEngineTime() < 0)
    {
        #if DEBUG
        PrintToChatAll("Target Time reached Action PointHurter killing itself");
        #endif
    
        CloseHandle(hurt);
        return Plugin_Stop;
    }
    
    #if DEBUG
    PrintToChatAll("Action PointHurter running");
    #endif
    
    if (!IsClientInGame(client)) client = -1;
    // dummy line to prevent compiling errors. the client data has to be read or the datapack becomes corrupted
    
    decl Float:targetVector[3];
    decl Float:distance;
    new Float:radiussetting = GetConVarFloat(CloudRadius);
    decl String:soundFilePath[256];
    GetConVarString(SoundPath, soundFilePath, sizeof(soundFilePath));
    new bool:shakeenabled = GetConVarBool(CloudShake);
    new damage = GetConVarInt(CloudDamage);
    new bool:slowenabled = GetConVarBool(CloudMeleeSlowEnabled);
    
    for (new target = 1; target <= MaxClients; target++)
    {
        if (!target
        || !IsClientInGame(target)
        || !IsPlayerAlive(target)
        || GetClientTeam(target) != 2)
        {
            continue;
        }

        GetClientEyePosition(target, targetVector);
        distance = GetVectorDistance(targetVector, g_pos);
        
        if (distance > radiussetting
        || !IsVisibleTo(g_pos, targetVector)) continue;

        EmitSoundToClient(target, soundFilePath);
        switch (GetConVarInt(DisplayDamageMessage))
        {
            case 1:
            PrintCenterText(target, "请即时避开有毒烟雾区域!");
            
            case 2:
            PrintHintText(target, "请即时避开有毒烟雾区域!");
            
            case 3:
            PrintToChat(target, "请即时避开有毒烟雾区域!");
        }
                
        
        if (shakeenabled)
        {
            new Handle:hBf = StartMessageOne("Shake", target);
            BfWriteByte(hBf, 0);
            BfWriteFloat(hBf,6.0);
            BfWriteFloat(hBf,1.0);
            BfWriteFloat(hBf,1.0);
            EndMessage();
            CreateTimer(1.0, StopShake, target);
        }
        
        if (slowenabled && !IsFakeClient(target))
        {
            isincloud[target] = true;
            CreateTimer(2.0, ClearMeleeBlock, target);
        }
        
        applyDamage(damage, target, client);
        
        //PrintToChatAll("请即时避开有毒烟雾区域!__舌头 _%N, ____%N__受伤害__%d", client, target, damage);
    }
    
    return Plugin_Continue;
}

public Action:HookSound_Callback(Clients[64], &NumClients, String:StrSample[PLATFORM_MAX_PATH], &Entity)
{
    //to work only on melee sounds, its 'swish' or 'weaponswing'
    if (StrContains(StrSample, "Swish", false) == -1) return Plugin_Continue;
    //so the client has the melee sound playing. OMG HES MELEEING!
    
    if (Entity > MAXPLAYERS) return Plugin_Continue; // bugfix for some people on L4D2
    
    //add in a 1 second delay so this doesnt fire every frame
    if (MeleeDelay[Entity]) return Plugin_Continue; //note 'Entity' means 'client' here
    MeleeDelay[Entity] = true;
    CreateTimer(1.0, ResetMeleeDelay, Entity);
    
    #if DEBUG
    PrintToChatAll("Melee detected via soundhook.");
    #endif
    
    if (isincloud[Entity]) SetEntData(Entity, meleeentinfo, 1.5, 4);    
    
    return Plugin_Continue;
}

public Action:ResetMeleeDelay(Handle:timer, any:client)
{
    MeleeDelay[client] = false;
}

public Action:ClearMeleeBlock(Handle:timer, Handle:target)
{
    isincloud[target] = false;
}

public Action:StopShake(Handle:timer, any:target)
{
    if (!target || !IsClientInGame(target)) return;
    
    new Handle:hBf = StartMessageOne("Shake", target);
    BfWriteByte(hBf, 0);
    BfWriteFloat(hBf, 0.0);
    BfWriteFloat(hBf, 0.0);
    BfWriteFloat(hBf, 0.0);
    EndMessage();
}

stock bool:IsPlayerSpawnGhost(client)
{
    if (GetEntData(client, propinfoghost, 1)) return true;
    return false;
}

// timer idea by dirtyminuth, damage dealing by pimpinjuice http://forums.alliedmods.net/showthread.php?t=111684
// added some L4D specific checks
static applyDamage(damage, victim, attacker)
{ 
    new Handle:dataPack = CreateDataPack();
    WritePackCell(dataPack, damage);  
    WritePackCell(dataPack, victim);
    WritePackCell(dataPack, attacker);
    
    CreateTimer(0.10, timer_stock_applyDamage, dataPack);
}

public Action:timer_stock_applyDamage(Handle:timer, Handle:dataPack)
{
    ResetPack(dataPack);
    new damage = ReadPackCell(dataPack);  
    new victim = ReadPackCell(dataPack);
    new attacker = ReadPackCell(dataPack);
    CloseHandle(dataPack);
    
    decl Float:victimPos[3], String:strDamage[16], String:strDamageTarget[16];
    
    if (!IsClientInGame(victim)) return;
    GetClientEyePosition(victim, victimPos);
    IntToString(damage, strDamage, sizeof(strDamage));
    Format(strDamageTarget, sizeof(strDamageTarget), "hurtme%d", victim);
    
    new entPointHurt = CreateEntityByName("point_hurt");
    if(!entPointHurt) return;
    
    new bool:reviveblock = GetConVarBool(CloudBlocksRevive);

    // Config, create point_hurt
    DispatchKeyValue(victim, "targetname", strDamageTarget);
    DispatchKeyValue(entPointHurt, "DamageTarget", strDamageTarget);
    DispatchKeyValue(entPointHurt, "Damage", strDamage);
    DispatchKeyValue(entPointHurt, "DamageType", reviveblock ? "65536" : "263168");
    DispatchSpawn(entPointHurt);
    
    // Teleport, activate point_hurt
    TeleportEntity(entPointHurt, victimPos, NULL_VECTOR, NULL_VECTOR);
    AcceptEntityInput(entPointHurt, "Hurt", (attacker > 0 && attacker < MaxClients && IsClientInGame(attacker)) ? attacker : -1);
    
    // Config, delete point_hurt
    DispatchKeyValue(entPointHurt, "classname", "point_hurt");
    DispatchKeyValue(victim, "targetname", "null");
    RemoveEdict(entPointHurt);
}

static bool:IsVisibleTo(Float:position[3], Float:targetposition[3])
{
    decl Float:vAngles[3], Float:vLookAt[3];
    
    MakeVectorFromPoints(position, targetposition, vLookAt); // compute vector from start to target
    GetVectorAngles(vLookAt, vAngles); // get angles from vector for trace
    
    // execute Trace
    new Handle:trace = TR_TraceRayFilterEx(position, vAngles, MASK_SHOT, RayType_Infinite, _TraceFilter);
    
    new bool:isVisible = false;
    if (TR_DidHit(trace))
    {
        decl Float:vStart[3];
        TR_GetEndPosition(vStart, trace); // retrieve our trace endpoint
        
        if ((GetVectorDistance(position, vStart, false) + TRACE_TOLERANCE) >= GetVectorDistance(position, targetposition))
        {
            isVisible = true; // if trace ray lenght plus tolerance equal or bigger absolute distance, you hit the target
        }
    }
    else
    {
        LogError("Tracer Bug: Player-Zombie Trace did not hit anything, WTF");
        isVisible = true;
    }
    CloseHandle(trace);
    
    return isVisible;
}

public bool:_TraceFilter(entity, contentsMask)
{
    if (!entity || !IsValidEntity(entity)) // dont let WORLD, or invalid entities be hit
    {
        return false;
    }
    
    return true;
}

/******************************************************
*	结束
*******************************************************/
